【CodeChef】 Queries on the String

来源:互联网 发布:启示录 知乎 编辑:程序博客网 时间:2024/06/06 03:06

前缀和(均摊复杂度可以水过)

#include<bits/stdc++.h>using namespace std;char inc;#define gc() getchar()#define isd(_t) isdigit(_t)inline void get(int& x){x =0 ;inc=gc();while(!isd(inc))inc=gc();while(isd(inc)){x=x*10+inc-'0';inc=gc();}}const int maxn = 100010;int n,m,a[maxn],sum[maxn];int main(){int op,x,y;get(n);get(m);for(int i=1;i<=n;i++)scanf("%1d",&a[i]),sum[i]=sum[i-1]+a[i],sum[i]%=3,a[i]%=3;for(int i=1;i<=m;i++){get(op),get(x),get(y);if(op==1){for(int j=x+1;j<=n;j++)sum[j]=(sum[j]+y-a[x]+3)%3;sum[x]=(sum[x-1]+y)%3;}else{int ans = 0;for(int j=x;j<=y;j++){for(int k=x;k<=j;k++){if((sum[j]-sum[k-1]+3)%3==0)ans++;}}printf("%d\n",ans);}}return 0;}

如果a,b满足前缀和取模相等,则a+1~b的和取模等于0

显然可以用线段树维护区间 前缀和取模为0,1,2的数量

单点修改区间查询


123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<queue>#include<set>#include<map>#define pa pair<int,int>#define inf 1000000000#define ll long longusing namespace std;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}char a[100005];struct data{int l,r,sum,v[3];}t[400005];int n,K;data merge(data a,data b){data t;t.l=a.l;t.r=b.r;t.sum=a.sum+b.sum;for(int i=0;i<3;i++){int tmp=(a.sum+i)%3;t.v[tmp]=a.v[tmp]+b.v[i];}return t;}void build(int k,int l,int r){t[k].l=l;t[k].r=r;int mid=(l+r)>>1;if(l==r){t[k].sum=(a[l]-'0')%3;t[k].v[t[k].sum]=1;return;}build(k<<1,l,mid);build(k<<1|1,mid+1,r);t[k]=merge(t[k<<1],t[k<<1|1]);}data query(int k,int x,int y){int l=t[k].l,r=t[k].r,mid=(l+r)>>1;if(l==x&&y==r)return t[k];if(y<=mid)return query(k<<1,x,y);else if(x>mid)return query(k<<1|1,x,y);else return merge(query(k<<1,x,mid),query(k<<1|1,mid+1,y));}void change(int k,int x,int val){int l=t[k].l,r=t[k].r,mid=(l+r)>>1;if(l==r){t[k].v[0]=t[k].v[1]=t[k].v[2]=0;t[k].v[val%3]=1;t[k].sum=val%3;return;}if(x<=mid)change(k<<1,x,val);else change(k<<1|1,x,val);t[k]=merge(t[k<<1],t[k<<1|1]);}int main(){n=read();K=read();scanf("%s",a+1);build(1,1,n);while(K--){int opt=read(),x=read(),y=read();if(opt==1)change(1,x,y);else {ll ans=0;data t=query(1,x,y);for(int i=0;i<3;i++)ans+=(ll)t.v[i]*(t.v[i]-1)/2;ans+=t.v[0];printf("%lld\n",ans);}}return 0;}


1 0
原创粉丝点击