제출 #1347212

#제출 시각아이디문제언어결과실행 시간메모리
1347212SmuggingSpunLegendary Dango Eater (JOI26_dango)C++20
100 / 100
624 ms322872 KiB
#include<bits/stdc++.h>
#define taskname "A"
using namespace std;
typedef long long ll;
const int lim = 5e5 + 5;
int n, q, a[lim];
ll k;
namespace sub1{
  void solve(){
    for(int _ = 0; _ < q; _++){
      int l, r;
      cin >> l >> r;
      ll ans = 0, delta = 0;
      for(int i = l; i <= r; i++){
        if(~i & 1){
          delta = max(0LL, delta - a[i]);
        }
        else if(delta + a[i] < k){
          delta += a[i];
        }
        else{
          ans += (a[i] - (k - delta)) / k + 1;
          delta = (a[i] - (k - delta)) % k;
        }
      }
      cout << ans << "\n";
    }
  }
}
namespace sub2{
  void solve(){
    vector<ll>f(n + 1);
    f[0] = 0;
    for(int i = 1; i <= n; i++){
      f[i] = f[i - 1];
      if(i & 1){
        f[i] += a[i] >> (k - 1);
      }
    }
    for(int _ = 0; _ < q; _++){
      int l, r;
      cin >> l >> r;
      cout << f[r] - f[l - 1] << "\n";
    }
  }
}
namespace sub3{
  struct Node{
    ll benefit[10], remain[10];
  };
  vector<Node>st;
  Node merge(Node a, Node b){
    Node c;
    for(int delta = 0; delta < k; delta++){
      c.benefit[delta] = a.benefit[delta] + b.benefit[a.remain[delta]];
      c.remain[delta] = b.remain[a.remain[delta]];
    }
    return c;
  }
  void build(int id, int l, int r){
    if(l == r){
      if(l & 1){
        for(int delta = 0; delta < k; delta++){
          if(delta + a[l] < k){
            st[id].benefit[delta] = 0;
            st[id].remain[delta] = delta + a[l];
          }
          else{
            st[id].benefit[delta] = (a[l] - (k - delta)) / k + 1;
            st[id].remain[delta] = (a[l] - (k - delta)) % k;
          }
        }
      }
      else{
        memset(st[id].benefit, 0, sizeof(st[id].benefit));
        for(int delta = 0; delta < k; delta++){
          st[id].remain[delta] = max(0, delta - a[l]); 
        }
      }
      return;
    }
    int m = (l + r) >> 1;
    build(id << 1, l, m);
    build(id << 1 | 1, m + 1, r);
    st[id] = merge(st[id << 1], st[id << 1 | 1]);
  }
  ll ans, delta;
  void walk(int id, int l, int r, int u, int v){
    if(l > v || r < u){
      return;
    }
    if(u <= l && v >= r){
      ans += st[id].benefit[delta];
      delta = st[id].remain[delta];
      return;
    }
    int m = (l + r) >> 1;
    walk(id << 1, l, m, u, v);
    walk(id << 1 | 1, m + 1, r, u, v);
  }
  void solve(){
    st.resize(n << 2 | 3);
    build(1, 1, n);
    for(int _ = 0; _ < q; _++){
      int l, r;
      cin >> l >> r;
      ans = delta = 0;
      walk(1, 1, n, l, r);
      cout << ans << "\n";
    }
  }
}
namespace sub456{
  ll delta[lim << 2], ans[lim << 2];
  vector<int>query_id[lim << 2];
  void walk(int id, int l, int r, int u, int v, int qid){
    if(l > v || r < u){
      return;
    }
    if(u <= l && v >= r){
      query_id[id].push_back(qid);
      return;
    }
    int m = (l + r) >> 1;
    walk(id << 1, l, m, u, v, qid);
    walk(id << 1 | 1, m + 1, r, u, v, qid);
  }
  struct Data{
    ll l, r, b, benefit;
    bool a;
    Data(){}
    Data(ll _l, ll _r, bool _a, ll _b, ll _benefit) : l(_l), r(_r), a(_a), b(_b), benefit(_benefit) {}
    friend bool operator <(const Data a, const Data b){
      return a.l < b.l;
    }
  };
  vector<Data>merge(vector<Data>left, vector<Data>right){
    vector<Data>ans;
    for(Data& cur : left){
      if(cur.a){
        ll l = cur.l + cur.b, r = cur.r + cur.b, start = cur.l;
        for(auto it = prev(upper_bound(right.begin(), right.end(), Data(l, -1, false, -1, -1))); it != right.end() && it->l <= r; it++){
          ll nl = it->l, nr = it->r;
          if(nl < l){
            if(nr <= r){
              ans.push_back(Data(start, start + nr - l, it->a, cur.b * it->a + it->b, cur.benefit + it->benefit));
              start += nr - l + 1;
            }
            else{
              ans.push_back(Data(start, cur.r, it->a, cur.b * it->a + it->b, cur.benefit + it->benefit));
              break;
            }
          }
          else if(nr <= r){
            ans.push_back(Data(start, start + nr - nl, it->a, cur.b * it->a + it->b, cur.benefit + it->benefit));
            start += nr - nl + 1;
          }
          else{
            ans.push_back(Data(start, cur.r, it->a, cur.b * it->a + it->b, cur.benefit + it->benefit));
            break;
          }
        }
      }
      else{
        auto it = prev(upper_bound(right.begin(), right.end(), Data(cur.b, -1, false, -1, -1)));
        ans.push_back(Data(cur.l, cur.r, false, cur.b * it->a + it->b, cur.benefit + it->benefit));
      }
    }
    return ans;
  }
  vector<Data>build(int id, int l, int r){
    vector<Data>ret;
    if(l == r){
      if(l & 1){
        if(a[l] % k == 0){
          ret.push_back(Data(0, k - 1, true, 0, a[l] / k));
        }
        else{
          ret.push_back(Data(0, k - a[l] % k - 1, true, a[l] % k, a[l] / k));
          ret.push_back(Data(k - a[l] % k, k - 1, true, -(k - a[l] % k), a[l] / k + 1));
        }
      }
      else if(a[l] >= k - 1){
        ret.push_back(Data(0, k - 1, false, 0, 0));
      }
      else{
        ret.push_back(Data(0, a[l], false, 0, 0));
        ret.push_back(Data(a[l] + 1, k - 1, true, -a[l], 0));
      }
    }
    else{
      int m = (l + r) >> 1;
      vector<Data>left = build(id << 1, l, m), right = build(id << 1 | 1, m + 1, r);
      ret = merge(left, right);
    }
    for(int& qid : query_id[id]){
      auto it = prev(upper_bound(ret.begin(), ret.end(), Data(delta[qid], -1, false, -1, -1)));
      ans[qid] += it->benefit;
      delta[qid] = delta[qid] * it->a + it->b;
    }
    return ret;
  }
  void solve(){
    memset(delta, 0, sizeof(delta));
    memset(ans, 0, sizeof(ans));
    for(int i = 1; i <= q; i++){
      int l, r;
      cin >> l >> r;
      walk(1, 1, n, l, r, i);
    }
    build(1, 1, n);
    for(int i = 1; i <= q; i++){
      cout << ans[i] << "\n";
    }
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  cin >> n >> q >> k;
  for(int i = 1; i <= n; i++){
    cin >> a[i];
  }
  if(q <= 10){
    sub1::solve();
  }
  else if(k <= 2){
    sub2::solve();
  }
  else if(k <= 10){
    sub3::solve();
  }
  else{
    sub456::solve();
  }
}

컴파일 시 표준 에러 (stderr) 메시지

Main.cpp: In function 'int main()':
Main.cpp:220:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  220 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...