CodeChef CBAL
题面:
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的更多相关文章
- 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ...
- 【BZOJ4260】 Codechef REBXOR 可持久化Trie
看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...
- codechef 两题
前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...
- codechef January Challenge 2014 Sereja and Graph
题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...
- BZOJ3509: [CodeChef] COUNTARI
3509: [CodeChef] COUNTARI Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 339 Solved: 85[Submit][St ...
- CodeChef FNCS
题面:https://www.codechef.com/problems/FNCS 题解: 我们考虑对 n 个函数进行分块,设块的大小为S. 每个块内我们维护当前其所有函数值的和,以及数组中每个元素对 ...
- codechef Prime Distance On Tree(树分治+FFT)
题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...
- BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )
树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
随机推荐
- MiniCodeEditor:只有168字节的在线Html/CSS/JavaScript编辑器
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:MiniCodeEditor:只有168字节的在线Html/CSS/JavaScript编辑器.
- MariaDB设置主从复制[转载]
3. MariaDB设置主从复制 标签: mariadbMySQL主从复制 翻译人员: 铁锚 翻译日期: 2013年12月25日 原文链接: Setting Up Replication 主从复制 ...
- Jmeter聚合报告分析
Label:每个 JMeter 的 element(例如 HTTP Request)都有一个 Name 属性,这里显示的就是 Name 属性的值 Average:平均响应时间--默认情况下是单个 Re ...
- 20169210《Linux内核原理与分析》第七周作业
第一部分:实验 首先还是网易云课堂的实验内容,扒开系统调用的三层皮(下),分为两部分: 1.给MenuOS增加time和time-asm命令 2.系统调用在内核代码中的处理过程 给MenuOS增加ti ...
- Conditionals with Omitted Operands (x ? : y)
Conditionals with Omitted Operands The middle operand in a conditional expression may be omitted. Th ...
- sqlServer将多字段设为主键方法
补充一下关于数据库多字段复合主键的设置. 首先一个表是不能有多个主键的.但是可以有多个字段组合成一个主键,这就是为什么有时候表里为什么会有多个字段都有主键的标志,那是因为他们组合成了一个主键了.我们可 ...
- 导入一个AndroidStudio工程作为一个Library Module
尊重劳动成果,转载请注明出处:http://blog.csdn.net/growth58/article/details/47441245 关注新浪微博:@于卫国 邮箱:yuweiguocn@gmai ...
- soap实例入门(转)
SOAP的HelloWord实例- - 1.1 前言 2005-3-2公司开会并分给我一个任务:写一个程序从福建移动的BOSS系统取出一些相关数据.我得到的资料仅仅有一个“福建移动BOSS与业务增值 ...
- getViewById和getLayoutInflater().inflate的用法
getViewById和getLayoutInflater().inflate得用法 1.什么是LayoutInflaterThis class is used to instantiate layo ...
- Eclipse3.7中搭建Android开发环境文档教程和视频教程
1.下载Eclipse3.7,登录http://www.eclipse.org/downloads/,下载Eclipse Classic 3.7: 2.安装ADT插件:下载好Eclipse后解压,运行 ...