Bzoj3343:教主的魔法:分块

来源:互联网 发布:suse linux防火墙 编辑:程序博客网 时间:2024/04/29 01:52

题目链接:3343:教主的魔法

对分块一直没有好感QAQ

但是身边神犇一直在用分块水题,于是我也来水道分块冷静下QwQ

#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define LL long longusing namespace std;const int maxn=1000010;const int maxb=1010;int n,m,p[maxn],blo,cnt=0;LL a[maxn];struct blo{int N,st,fi;LL c[maxb],add;void init(){N=0;for (int i=st;i<=fi;++i)    c[++N]=a[i];sort(c+1,c+N+1);}int getans(int x){int l=1,r=N;while (l<r){int mid=(l+r)>>1;if (c[mid]+add<x) l=mid+1;else r=mid;}if (c[l]+add<x) l++;return (N-l+1)>0?(N-l+1):0;}}b[maxb];void change(){int x,y,z; scanf("%d%d%d",&x,&y,&z);if (p[x]==p[y]){    for (int i=x;i<=y;++i) a[i]+=z;    b[p[x]].init();}else if (p[x]!=p[y]){for (int i=x;i<=b[p[x]].fi;++i) a[i]+=z;for (int i=b[p[y]].st;i<=y;++i) a[i]+=z;b[p[x]].init(); b[p[y]].init();for (int i=p[x]+1;i<=p[y]-1;++i) b[i].add+=z;}}void solve(){int x,y,z; scanf("%d%d%d",&x,&y,&z);if (p[x]==p[y]){int ret=0;for (int i=x;i<=y;++i) if (a[i]>=z) ret++;printf("%d\n",ret); return;}else if (p[x]!=p[y]){int ret=0;for (int i=x;i<=b[p[x]].fi;++i)    if (a[i]>=z) ret++;for (int i=b[p[y]].st;i<=y;++i)    if (a[i]>=z) ret++;for (int i=p[x]+1;i<=p[y]-1;++i)    ret+=b[i].getans(z);printf("%d\n",ret); return;}}int main(){scanf("%d%d",&n,&m); blo=(int)sqrt(n);for (int i=1;i<=n;++i){scanf("%d",&a[i]);p[i]=(i-1)/blo+1;if (p[i]!=p[i-1]){b[cnt].fi=i-1;b[++cnt].st=i;}}b[cnt].fi=n;for (int i=1;i<=cnt;++i) b[i].init();for (int i=1;i<=m;++i){char s[6]; scanf("%s",s);if (s[0]=='M') change();else if (s[0]=='A') solve();}}


4 0
原创粉丝点击