标签:
只能说太弱了。。。 别人眼中的水题。。 我到现在还不知道能不能写出~~
维护前缀和并且应用同余定理: (sum[r] - sum[l-1])%3 == 0 -> (sum[r]%3 - sum[l-1]%3)%3 == 0 -> sum[r]%3 == sum[l-1]%3
线段树维护前缀和中0,1,2的个数即可;
发来kuangbin巨的代码;
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int MAXN = 100010; struct Node{ int l,r; int c[3]; int add; }segTree[MAXN<<2]; void Update_Add(int i,int val){ int cc[3]; for(int j = 0;j < 3;j++)cc[j] = segTree[i].c[(j-val+3)%3]; for(int j = 0;j < 3;j++)segTree[i].c[j] = cc[j]; segTree[i].add += val; segTree[i].add %= 3; } void push_up(int i){ for(int j = 0;j < 3;j++) segTree[i].c[j] = segTree[i<<1].c[j]+segTree[(i<<1)|1].c[j]; } void push_down(int i){ if(segTree[i].add){ Update_Add(i<<1,segTree[i].add); Update_Add((i<<1)|1,segTree[i].add); segTree[i].add = 0; } } int a[MAXN],b[MAXN]; void build(int i,int l,int r){ segTree[i].l = l; segTree[i].r = r; for(int j = 0;j < 3;j++) segTree[i].c[j] = 0; segTree[i].add = 0; if(l == r){ segTree[i].c[b[l]]++; return; } int mid = (l+r)/2; build(i<<1,l,mid); build((i<<1)|1,mid+1,r); push_up(i); } void update(int i,int l,int r,int val){ if(val == 0)return; if(segTree[i].l == l && segTree[i].r == r){ Update_Add(i,val); return; } push_down(i); int mid = (segTree[i].l + segTree[i].r)/2; if(r <= mid)update(i<<1,l,r,val); else if(l > mid)update((i<<1)|1,l,r,val); else { update(i<<1,l,mid,val); update((i<<1)|1,mid+1,r,val); } push_up(i); } int query(int i,int l,int r,int c0){ if(segTree[i].l == l && segTree[i].r == r) return segTree[i].c[c0]; push_down(i); int mid = (segTree[i].l + segTree[i].r)/2; if(r <= mid)return query(i<<1,l,r,c0); else if(l > mid)return query((i<<1)|1,l,r,c0); else { return query(i<<1,l,mid,c0)+query((i<<1)|1,mid+1,r,c0); } } char str[MAXN]; int main(){ int n,m; while(scanf("%d%d",&n,&m) == 2){ scanf("%s",str); b[0] = 0; n++; a[1] = b[1] = 0; for(int i = 2;i <= n;i++){ a[i] = str[i-2]-‘0‘; b[i] = (b[i-1]+a[i])%3; } build(1,1,n); while(m--){ int op; scanf("%d",&op); if(op == 1){ int x,y; scanf("%d%d",&x,&y); x++; update(1,x,n,(y-a[x]+3)%3); a[x] = y; } else { int x,y; scanf("%d%d",&x,&y); y++; long long ans = 0; int tmp = query(1,x,y,0); ans += (long long)tmp*(tmp-1)/2; tmp = query(1,x,y,1); ans += (long long)tmp*(tmp-1)/2; tmp = query(1,x,y,2); ans += (long long)tmp*(tmp-1)/2; cout<<ans<<endl; } } } }
CodeChef January Challenge Queries on the StringSolved
标签:
原文地址:http://www.cnblogs.com/ltwy/p/4202292.html