题面:

https://www.codechef.com/problems/CBAL

题解:

可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26,

所以我们状态压缩,记 a[i]表示 s[1..i]所有字符的奇偶性状态,

那么子串 s[L..R]是平衡字符串当且仅当a[L-1]=a[R]。

我们对 a 离散化后就可以让其在[1,n]的范围内。

如果没有强制在线,那么我们很容易用莫队算法解决。

记录当前范围所有状态的出现位置下标的 0~2 次方之和,

利用(a-b)2=a2-2ab+b2可以很方便地实现在首尾添加元素。

那么这题强制在线,我们用分块算法即可。

记录 ans[i][j][type]表示块 i~块 j 的 type权值,

f[i][j][k]表示前 i 个块中权值 j 出现位置下标的 k 次方和,

那么查询一个区间我们可以先得到其完整覆盖的块的答案以及状态,

然后用上述方法在块的首尾加入剩下的元素并更新答案即可。

code:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
typedef long long int64;
const int maxs=;
const int maxn=;
char s[maxn];
int T,n,lim,siz,cnt,q,x,y,op;
int a[maxn],tmp[maxn],bel[maxn];
int64 f[maxs][maxn][],ans[maxs][maxs][],sum[maxn][],A,B;
struct Data{
int l,r;
}block[maxn];
void init(){
for (int i=;i<=n;i++) a[i]=a[i-]^(<<(s[i]-'a'));
memcpy(tmp,a,sizeof(tmp)),sort(tmp,tmp+n+),cnt=unique(tmp,tmp+n+)-tmp;
for (int i=;i<=n;i++) a[i]=upper_bound(tmp,tmp+cnt,a[i])-tmp;
memset(block,-,sizeof(block));
for (int i=;i<=n;i++){
bel[i]=i/siz+;
if (block[bel[i]].l==-) block[bel[i]].l=i;
block[bel[i]].r=i;
}
lim=bel[n];
for (int i=;i<=lim;i++){
for (int j=;j<=cnt;j++) for (int k=;k<=;k++) f[i][j][k]=f[i-][j][k];
for (int j=block[i].l;j<=block[i].r;j++){
f[i][a[j]][]++;
f[i][a[j]][]+=j;
f[i][a[j]][]+=1LL*j*j;
}
}
for (int i=;i<=lim;i++){
for (int j=i;j<=lim;j++){
for (int k=;k<=;k++) ans[i][j][k]=ans[i][j-][k];
for (int k=block[j].l;k<=block[j].r;k++){
ans[i][j][]+=sum[a[k]][];
ans[i][j][]+=1LL*k*sum[a[k]][]-sum[a[k]][];
ans[i][j][]+=1LL*k*k*sum[a[k]][]-2LL*k*sum[a[k]][]+sum[a[k]][];
sum[a[k]][]++;
sum[a[k]][]+=k;
sum[a[k]][]+=1LL*k*k;
}
}
for (int j=;j<=cnt;j++) for (int k=;k<=;k++) sum[j][k]=;
}
}
void query(int l,int r,int op){
if (l>r) swap(l,r); l--;
int st=bel[l],ed=bel[r]; int64 res[]={,,},tmp[];
if (st!=ed){
if (l>block[st].l) st++;
if (r<block[ed].r) ed--;
for (int i=;i<=;i++) res[i]+=ans[st][ed][i];
if (st!=bel[l]){
for (int i=block[bel[l]].r;i>=l;i--){
for (int j=;j<=;j++) tmp[j]=f[ed][a[i]][j]-f[st-][a[i]][j]+sum[a[i]][j];
res[]+=tmp[];
res[]+=tmp[]-1LL*i*tmp[];
res[]+=1LL*i*i*tmp[]-2LL*i*tmp[]+tmp[];
sum[a[i]][]++;
sum[a[i]][]+=i;
sum[a[i]][]+=1LL*i*i;
}
}
if (ed!=bel[r]){
for (int i=block[bel[r]].l;i<=r;i++){
for (int j=;j<=;j++) tmp[j]=f[ed][a[i]][j]-f[st-][a[i]][j]+sum[a[i]][j];
res[]+=tmp[];
res[]+=1LL*i*tmp[]-tmp[];
res[]+=1LL*i*i*tmp[]-2LL*i*tmp[]+tmp[];
sum[a[i]][]++;
sum[a[i]][]+=i;
sum[a[i]][]+=1LL*i*i;
}
}
if (ed!=bel[r]){
for (int i=block[bel[r]].l;i<=r;i++){
sum[a[i]][]--;
sum[a[i]][]-=i;
sum[a[i]][]-=1LL*i*i;
}
}
if (st!=bel[l]){
for (int i=block[bel[l]].r;i>=l;i--){
sum[a[i]][]--;
sum[a[i]][]-=i;
sum[a[i]][]-=1LL*i*i;
}
}
}
else{
if (l==block[st].l&&r==block[ed].r) res[op]=ans[st][ed][op];
else{
for (int i=l;i<=r;i++){
res[]+=sum[a[i]][];
res[]+=1LL*i*sum[a[i]][]-sum[a[i]][];
res[]+=1LL*i*i*sum[a[i]][]-2LL*i*sum[a[i]][]+sum[a[i]][];
sum[a[i]][]++;
sum[a[i]][]+=i;
sum[a[i]][]+=1LL*i*i;
}
for (int i=l;i<=r;i++){
sum[a[i]][]--;
sum[a[i]][]-=i;
sum[a[i]][]-=1LL*i*i;
}
}
}
A=B,B=res[op];
printf("%lld\n",res[op]);
}
int main(){
for (read(T);T;T--){
scanf("%s",s+),n=strlen(s+),siz=sqrt(n),A=B=,init();
for (read(q);q;q--) read(x),x=(x+A)%n+,read(y),y=(y+B)%n+,read(op),query(x,y,op);
}
return ;
}

CodeChef CBAL的更多相关文章

  1. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  2. 【BZOJ4260】 Codechef REBXOR 可持久化Trie

    看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...

  3. codechef 两题

    前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...

  4. codechef January Challenge 2014 Sereja and Graph

    题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...

  5. BZOJ3509: [CodeChef] COUNTARI

    3509: [CodeChef] COUNTARI Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 85[Submit][St ...

  6. CodeChef FNCS

    题面:https://www.codechef.com/problems/FNCS 题解: 我们考虑对 n 个函数进行分块,设块的大小为S. 每个块内我们维护当前其所有函数值的和,以及数组中每个元素对 ...

  7. codechef Prime Distance On Tree(树分治+FFT)

    题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...

  8. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

  9. BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )

    从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...

随机推荐

  1. Spring 4.x org.springframework.http.converter.json.MappingJacksonHttpMessageConverter ClassNotFoundException:

    Spring 4.x The first major version of Jackson is no longer supported in Spring 4. The class you want ...

  2. BBC 生命大设计

    BBC霍金的生命的意义一视频中,有一段图案特别漂亮,于是我就写了一下,具体的繁殖规则是这样的:有存活体和死方格两个部分构成,我分别用 ' * ' 和 ‘  ’ 表示.当一个存活体周围有超过三个存活体时 ...

  3. hdu 2821 Pusher(dfs)

    Problem Description PusherBoy is an online game http://www.hacker.org/push . There is an R * C grid, ...

  4. 将文件的图标添加到LISTVIEW中

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. Android 完美退出 App (Exit)

    最近两天为了解决Android上面退出程序问题折腾了半死,在google & baidu 上面找了很久.很久出来的完全千篇一律,说的方法有三,但是经过我试验后全部不行. 三个方法分别是: ki ...

  6. mybatis10 实现类代理对象开发

    mapper实现类代理对象开发 要想让mybatis自动创建dao接口实现类的代理对象,必须遵循一些规则: SqlSession sqlSession = sqlSessionFactory.open ...

  7. Java基础知识强化之集合框架笔记50:Map集合之Map集合的概述和特点

    1. Map集合的概述: public interface Map<K,V> 作为学生来说,是根据学号来区分不同的学生的,那么假设我现在已经知道了学生的学号,我要根据学号去获取学生姓名,请 ...

  8. 关于Android NDK

    把解压后的ndk放在自己想放的位置 环境变量:ndk根目录添加到PATH=$PATH:<ndk-root-path> 使用NDK:在自己工作目录(可以是随意位置)下创建<Test&g ...

  9. RHEL7虚拟机中不重启的情况下加新硬盘及扩展根分区容量

    在VMware中添加一块新的5G硬盘 显示当前分区 # fdisk -l 通常在你在虚拟机中添加一块新硬盘时,你可能会看到新硬盘没有自动加载.这是因为连接到硬盘的SCSI总线需要重新扫描来使得新硬盘可 ...

  10. PHP 发邮件不换行

    Content-Type:用于定义用户的浏览器或相关设备如何显示将要加载的数据,或者如何处理将要加载的数据 MIME:MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件 ...