BZOJ3343: 教主的魔法

来源:互联网 发布:散热片数量的算法公式 编辑:程序博客网 时间:2024/04/26 06:28

因为询问大于等于一个值的数量,还要支持区间加,考虑操作数不多,可以分块
因为操作数很少,每个块内排序,询问时两端点的块扫一遍,中间的块二分,修改时如果覆盖了整个块就给这个块打个标记,否则暴力修改后重新排序,每次修改&询问复杂度O(nlogn)


code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxn = 1100000;struct node{       int i;    ll x;}a[maxn];ll f[maxn];int n,N,m;int id[maxn],st[maxn];char str[1110];int find_f(int l,int r,ll x){    while(l<=r)    {        int mid=(l+r)>>1;        if(a[mid].x>=x)l=mid+1;        else r=mid-1;    }    return l-1;}bool cmp(node x,node y){return x.x>y.x;}int main(){    scanf("%d%d",&n,&m); N=sqrt(n);    for(int i=1;i<=n;i++)     {        id[i]=(i-1)/N+1;        scanf("%d",&a[i].x);        a[i].i=i;    }    st[1]=1;  st[id[n]+1]=n+1;    for(int i=2;i<=id[n];i++) st[i]=st[i-1]+N;    for(int i=1;i<=id[n];i++) sort(a+st[i],a+st[i+1],cmp);    while(m--)    {        scanf("%s",str);        int x,y; ll c; scanf("%d%d%lld",&x,&y,&c);        if(str[0]=='A')        {            int t1=id[x],t2=id[y];            int ret=0;            if(t1+1>=t2)            {                for(int i=st[t1];i<st[t2+1];i++)                    if(a[i].i>=x&&a[i].i<=y&&a[i].x+f[id[i]]>=c)ret++;            }            else            {                for(int i=st[t1];i<st[t1+1]&&a[i].x+f[t1]>=c;i++)                    if(a[i].i>=x)ret++;                for(int i=t1+1;i<t2;i++)                    ret+=find_f(st[i],st[i+1]-1,c-f[i])-st[i]+1;                for(int i=st[t2];i<st[t2+1]&&a[i].x+f[t2]>=c;i++)                    if(a[i].i<=y)ret++;            }            printf("%d\n",ret);        }           else        {            int t1=id[x],t2=id[y];            if(t1==t2)            {                for(int i=st[t1];i<st[t1+1];i++)                    if(a[i].i>=x&&a[i].i<=y)a[i].x+=c;                sort(a+st[t1],a+st[t1+1],cmp);            }            else            {                for(int i=st[t1];i<st[t1+1];i++)                    if(a[i].i>=x)a[i].x+=c;                sort(a+st[t1],a+st[t1+1],cmp);                for(int i=t1+1;i<t2;i++)                    f[i]+=c;                for(int i=st[t2];i<st[t2+1];i++)                    if(a[i].i<=y)a[i].x+=c;                sort(a+st[t2],a+st[t2+1],cmp);            }        }    }    return 0;}
0 0
原创粉丝点击