Gym

来源:互联网 发布:宏村 知乎 编辑:程序博客网 时间:2024/05/16 12:58

链接:http://codeforces.com/gym/100741/problem/A
分析:“+ p r”:下标为p的数加上r;
“- p r”:下标为p的数加上r;
“s l r mod”:求[l,r]中模m后等于mod的数之和。
时间限制比较小,用树状数组快,开m个树状数组,每一个存储取模后值相同的数。注意用long long
代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<iomanip>#include<cmath>#include<vector>#include<map>#include<set>#include<queue>#define INF 0x3f3f3f3f#define LL long long#define ee 0.000000001#define bug "++++++++++++++++"#define lowbit(x) x&-xusing namespace std;const int maxn=100005;long long n,m;long long arr[maxn];long long C[2*maxn][15];//让arr[x]加上或者减去dvoid add(long long x,long long d,long long mod){    while(x<=n)    {        C[x][mod]+=d;        x+=lowbit(x);    }}//求arr[1...x]的和long long sum(int x,long long mod){    long long ret=0;    while(x>0)    {        ret+=C[x][mod];        x-=lowbit(x);    }    return ret;}int main(){    scanf("%lld%lld",&n,&m);    for(long long i=1;i<=n;i++)    {        scanf("%lld",&arr[i]);        add(i,arr[i],arr[i]%m);  //注意取模,存进不同的树状数组    }    int q;    scanf("%d",&q);    while(q--)    {        getchar();        char op;        scanf("%c",&op);        if(op=='+')        {            long long index,value;            scanf("%lld%lld",&index,&value);            add(index,-arr[index],arr[index]%m);   //先把原来的值改为0            arr[index]+=value;            add(index,arr[index],(arr[index])%m);//再修改加上value后的值,并修改树状数组            printf("%lld\n",arr[index]);        }        else if(op=='-')        {            long long index,value;            scanf("%lld%lld",&index,&value);            add(index,-arr[index],arr[index]%m);            if(value<=arr[index])            {                arr[index]-=value;            }            add(index,arr[index],arr[index]%m);           printf("%lld\n",arr[index]);        }        else if(op=='s')        {            long long l,r,mod;            scanf("%lld%lld%lld",&l,&r,&mod);            printf("%lld\n",sum(r,mod)-sum(l-1,mod));  //arr[l,r]之间的和        }    }}
原创粉丝点击