codechef CBAL

传送门:https://www.codechef.com/problems/CBAL

思路:

先求一遍出现次数前缀和,我们只管每个字母出现次数奇偶性,所以可以把状态压缩一下,离散化之后就只有最多n个状态
对于子串[l,r]如果s[l-1]==s[r],那么[l,r]合法
f 前i块,状态j,出现下标k次方之和,ans 块i到j的答案
完整的块直接得答案,外面剩余的一个一个加进来
假设现在加进来的位置是b,状态为s[b]
那么对于0次方 就不说什么了,就是s[b]状态的出现次数
对于1次方 由Σ(b-i)^1=b*sum[i][[0]-sum[i][1](s[i]==s[b])可算得
对于2次方 由Σ(b-i)^2=(b^2-2*b*sum[i][1]+sum[i][2])(s[i]==s[b])可算得

#include
#include
#include
#include
#include
#include
const int maxn=100010,maxb=320;
typedef long long ll;
using namespace std;
int cas,n,Q,sta[maxn],pw[29],tmp[maxn],cnt,bcnt,bsz,bel[maxn],seq[maxn];char s[maxn];
ll A,B,lastans,f[maxb][maxn][3],ans[maxb][maxb][3],sum[maxn][3];
struct seg{int l,r;}blk[maxb];

void init(){
	pw[0]=1;for (int i=1;i<=26;i++) pw[i]=pw[i-1]<<1;
	scanf("%s",s+1),n=strlen(s+1),scanf("%d",&Q);
	sta[0]=tmp[0]=0;
	for (int i=1;i<=n;i++) sta[i]=sta[i-1]^pw[s[i]-'a'],tmp[i]=sta[i];
	sort(tmp,tmp+n+1),cnt=unique(tmp,tmp+n+1)-tmp;
	for (int i=0;i<=n;i++) sta[i]=upper_bound(tmp,tmp+cnt,sta[i])-tmp;
}

void trans(ll a[],ll sum[],int b,int op){
	a[0]+=sum[0];
	a[1]+=op*(sum[0]*b-sum[1]);
	a[2]+=sum[0]*b*b-2ll*sum[1]*b+sum[2];
	sum[0]++,sum[1]+=b,sum[2]+=1ll*b*b;
}

void prework(){
	for (int i=1;i=L;i--){
			int stt=sta[i];
			if (!sum[stt][0]){
				seq[++cnt]=stt;
				for (int k=0;k<3;k++)
					sum[stt][k]=getf(st+1,ed-1,stt,k);
			}
			trans(res,sum[stt],i,-1);
		}
		for (int i=blk[ed].l;i<=R;i++){
			int stt=sta[i];
			if (!sum[stt][0]){
				seq[++cnt]=stt;
				for (int k=0;k<3;k++)
					sum[stt][k]=getf(st+1,ed-1,stt,k);
			}
			trans(res,sum[stt],i,1);
		}
	}
	else{
		for (int i=L;i<=R;i++){
			int stt=sta[i];
			if (!sum[stt][0]) seq[++cnt]=stt;
			trans(res,sum[stt],i,1);
		}
	}
	for (int i=1;i<=cnt;i++) for (int j=0;j<3;j++) sum[seq[i]][j]=0;
	return res[type];
}

void work(){
	lastans=A=B=0;
	for (int i=1,x,y,type;i<=Q;i++){
		scanf("%d%d%d",&x,&y,&type);
		x=(x+A)%n+1,y=(y+B)%n+1;
		if (x>y) swap(x,y);
		lastans=query(x-1,y,type);
		printf("%lld\n",lastans);
		A=B,B=lastans;
	}
}

int main(){
	scanf("%d",&cas);
	while (cas--) init(),prework(),work();
	return 0;
}



转载于:https://www.cnblogs.com/thythy/p/5493641.html

你可能感兴趣的:(codechef CBAL)