1. 程式人生 > >洛谷P2801 教主的魔法 分塊

洛谷P2801 教主的魔法 分塊

我們將序列分成 n \sqrt{n} 塊,維護一個 A [ i ]

A[i] a r r [ i ] arr[i] ,即為原序列和排好序的序列。
這裡的原序列指的是同一個快中的元素的相對位置不變,這樣才可以進行修改。
Code:

#include<algorithm>
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;
const int maxn = 1000000 + 3;
int n, q, block, belong[maxn];
long long arr[maxn], lazy[maxn], A[maxn];
struct Data_Structure
{
    inline
int start(int i) { return (i - 1) * block + 1;} inline int end(int i) { return i * block;} inline void init() { scanf("%d%d",&n,&q); block = sqrt(n); for(int i = 1;i <= n; ++i) { scanf("%lld",&arr[i]); A[i] = arr[i]; belong[i] = (i - 1) / block + 1; } for(int i = 1; end(i) <= n; ++i) sort(arr + start(i), arr + min(end(i), n) + 1); } inline void update(int L, int R, int delta){ for(int i = L; i <= min(end(belong[L]), R); ++i) A[i] += delta; for(int i = start(belong[L]); i <= min(n,end(belong[L])); ++i) arr[i] = A[i]; sort(arr + start(belong[L]), arr + 1 + min(n, end(belong[L]))); if(belong[L] != belong[R]) { for(int i = start(belong[R]); i <= R; ++i) A[i] += delta; for(int i = start(belong[R]); i <= R; ++i) arr[i] = A[i]; sort(arr + start(belong[R]), arr + 1 + min(end(belong[R]), n)) ; } for(int i = belong[L] + 1; i < belong[R] ; ++i) lazy[i] += delta; } inline int solve(int u,long long C) { int l = start(u), r = end(u), ans = 0; int R = r; C -= lazy[u]; while(l <= r) { int mid = (l + r) >> 1; if(arr[mid] >= C) ans = mid, r = mid - 1; else l = mid + 1; } ans = ans == 0 ? 0 : R - ans + 1; return ans; } inline int query(int L, int R, long long C){ int tmp = 0; for(int i = L; i <= min(end(belong[L]), R); ++i) if(arr[i] + lazy[belong[L]] >= C) ++tmp; if(belong[L] != belong[R]) { for(int i = start(belong[R]); i <= R; ++i) if(arr[i] + lazy[belong[R]] >= C) ++tmp; } for(int i = belong[L] + 1; i < belong[R]; ++i) tmp += solve(i, C); return tmp; } }T; int main() { T.init(); for(int i = 1;i <= q; ++i) { char opt[10]; int l, r, k; scanf("%s",opt); scanf("%d%d%d",&l,&r,&k); if(opt[0] == 'M') T.update(l, r, k); if(opt[0] == 'A') printf("%d\n", T.query(l, r, k)); } return 0; }