Submission #1367178

#TimeUsernameProblemLanguageResultExecution timeMemory
1367178vlomaczkLegendary Dango Eater (JOI26_dango)C++20
23 / 100
2597 ms223952 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;
#define ff first
#define ss second
#define pi pair<ll, ll>
#define pll pair<long long, long long>
#define vi vector<ll>
#define vll vector<long long>
#define vpi vector<pair<ll,ll>>
#define vpll vector<pair<long long, long long>>
#define pb push_back
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define sz(x) (ll)(x).size()
#define forall(it,x) for(auto& it:(x))
#define mp make_pair
pi operator+(pi a, pi b) { return mp(a.ff+b.ff, a.ss+b.ss); }
pi operator-(pi a, pi b) { return mp(a.ff-b.ff, a.ss-b.ss); }
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

ll base = 1<<20;
struct SegTree {
	vector<ll> T;
	SegTree() {
		T.assign(2*base, 1e9);
	}

	void update(ll a, ll b, ll val) {
		if(a>b)return;
		if(a==b) {
			T[a+base] = min(T[a+base], val);
			return;
		}
		a+=base-1;
		b+=base+1;
		while(a/2 != b/2) {
			if(a%2==0) T[a+1] = min(T[a+1], val);
			if(b%2==1) T[b-1] = min(T[b-1], val);
			a/=2; b/=2;
		}
	}
	ll query(ll x) {
		ll res = 1e9;
		x+=base;
		while(x > 0) {
			res = min(res, T[x]);
			x/=2;
		}
		return res;
	}
};

signed main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	ll n, q, K;
	cin >> n >> q >> K;
	vector<ll> A(n+1);
	for(ll i=1; i<=n; ++i) cin >> A[i];
	for(ll i=2; i<=n; i+=2) A[i] *= -1;
	vector<ll> P(n+1);
	for(ll i=1; i<=n; ++i) P[i] = P[i-1] + A[i];
	vector<ll> rem;
	for(ll i=1; i<=n; ++i) rem.pb(((P[i-1]%K)+K)%K);
	sort(all(rem));
	rem.erase(unique(all(rem)), rem.end());
	vector<ll> nxt(n+1, n+1);
	SegTree st;	
	for(ll i=n; i>=1; --i) {
		if(A[i] <= -K) st.update(0, base-1, i);
		else if(A[i] < 0) {
			ll pp = ((P[i-1]%K)+K)%K;

			ll L = upper_bound(all(rem), pp + A[i]) - rem.begin();
			ll R = upper_bound(all(rem), pp) - rem.begin() - 1;
			st.update(L,R,i);

			L = upper_bound(all(rem), max(pp, pp + A[i] + K)) - rem.begin();
			st.update(L,base-1,i);

			for(ll j=0; j<(ll)rem.size(); ++j) {
				if(pp >= rem[j]) {
					if(rem[j] > pp + A[i]) st.update(j,j,i);
				} else {
					if(rem[j] > pp + A[i] + K) st.update(j,j,i);
				}
			}
		}
		ll idx = lower_bound(rem.begin(), rem.end(), ((P[i-1]%K)+K)%K) - rem.begin();
		nxt[i] = min(nxt[i], st.query(idx));
	}
	// for(ll i=1; i<=n; ++i) cout << nxt[i] << " ";
	// cout << "\n";

	ll maxlog = 20;
	vector<vector<pair<ll, ll>>> jump(n+1, vector<pi>(maxlog+1, {n+5, 0}));
	for(ll i=1; i<=n; ++i) {
		jump[i][0] = {nxt[i]+1, (P[nxt[i]-1] - P[i-1]) / K};
	}
	for(ll j=1; j<=maxlog; ++j) {
		for(ll i=1; i<=n; ++i) {
			if(jump[i][j-1].first > n) continue;
			jump[i][j].first = jump[jump[i][j-1].first][j-1].first;
			jump[i][j].second = jump[i][j-1].second + jump[jump[i][j-1].first][j-1].second;
		}
	}
	while(q--) {
		ll l, r; 
		cin >> l >> r;
		if(A[l] < 0) l++;
		if(l > r) {
			cout << "0\n";
			continue;
		}

		ll res = 0;
		for(ll j=maxlog; j>=0; --j) {
			if(l > n) break;
			if(jump[l][j].first-1 <= r) {
				res += jump[l][j].second;
				l = jump[l][j].first;
			}
		}
		res += (P[r] - P[l-1]) / K;
		cout << res << "\n";
	}

	return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...