传送门

由乃的题还是一如既往的可怕……

先放上原题解

标解:

一个区间可以重排成为回文串,即区间中最多有一个字母出现奇数次,其他的都出现偶数次

发现这个和  类似





这样如果一个区间的  和为  或者  ,则这个区间可以重排成为回文串,即回归天空

把每个位置的值变为前缀  和,那么区间  可以回归天空当且仅当  为  或者 

 即  的异或和

这样用莫队算法,可以做到  的复杂度

然后怎么用莫队?可以参考一下这道题目->异或序列

考虑区间$[l,r]->[l,r+1]$就是要看这个区间里有多少前缀异或$a[r+1]$等于$0$或$1<<x$

那么只要用桶存起来就好了

 //minamoto
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=,M=(<<)+;
int a[N],rt[N],l,r,n,m,bl;char s[N];
struct node{
int l,r,id;
inline bool operator <(const node b)const
{
if(rt[l]!=rt[b.l]) return l<b.l;
return rt[l]&?r<b.r:r>b.r;
}
}q[N];
unsigned short c[M];
int ans[N],ansn;
inline void add(int x){
ansn+=c[a[x]];
for(int i=;i<;++i) ansn+=c[a[x]^(<<i)];
++c[a[x]];
}
inline void del(int x){
--c[a[x]];
ansn-=c[a[x]];
for(int i=;i<;++i) ansn-=c[a[x]^(<<i)];
}
int main(){
n=read(),m=read(),bl=sqrt(n);
scanf("%s",s+);
for(int i=;i<=n;++i) a[i]=(<<(s[i]-'a'))^a[i-],rt[i]=(i-)/bl+;
for(int i=;i<=m;++i)
q[i].l=read()-,q[i].r=read(),q[i].id=i;
sort(q+,q++m);
l=,r=,c[]=;
for(int i=;i<=m;++i){
while(l>q[i].l) add(--l);
while(r<q[i].r) add(++r);
while(l<q[i].l) del(l++);
while(r>q[i].r) del(r--);
ans[q[i].id]=ansn;
}
for(int i=;i<=m;++i) print(ans[i]);
Ot();
return ;
}

然而实际上每一次都要做位运算太慢了,可以直接一波离散把所有能转移到的状态找出来,然后就会快很多(上面那个 7040ms,下面这个938ms)

 //minamoto
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=,M=(<<)+;
int a[N],b[N],rt[N],l,r,n,m,bl,ver[N*],Next[N*],head[N],tot;char s[N];
struct node{
int l,r,id;
inline bool operator <(const node b)const
{
if(rt[l]!=rt[b.l]) return l<b.l;
return rt[l]&?r<b.r:r>b.r;
}
}q[N];
unsigned short c[M];
int ans[N],ansn;
inline void addedge(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
inline void add(int x){
for(int i=head[a[x]];i;i=Next[i]) ansn+=c[ver[i]];
++c[a[x]];
}
inline void del(int x){
--c[a[x]];
for(int i=head[a[x]];i;i=Next[i]) ansn-=c[ver[i]];
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read(),bl=sqrt(n);
scanf("%s",s+);
for(int i=;i<=n;++i) b[i]=a[i]=(<<(s[i]-'a'))^a[i-],rt[i]=i/bl;
sort(b,b++n);
int k=unique(b,b++n)-b;
for(int i=;i<k;++i){
for(int j=;j<;++j){
int t=b[i]^(<<j);
int y=lower_bound(b,b+k,t)-b;
if(b[y]==t) addedge(i,y);
}
addedge(i,i);
}
for(int i=;i<=n;++i) a[i]=lower_bound(b,b+k,a[i])-b;
for(int i=;i<=m;++i)
q[i].l=read()-,q[i].r=read(),q[i].id=i;
sort(q+,q++m);
l=,r=,c[]=;
for(int i=;i<=m;++i){
while(l>q[i].l) add(--l);
while(r<q[i].r) add(++r);
while(l<q[i].l) del(l++);
while(r>q[i].r) del(r--);
ans[q[i].id]=ansn;
}
for(int i=;i<=m;++i) print(ans[i]);
Ot();
return ;
}

洛谷P3604 美好的每一天(莫队)的更多相关文章

  1. B 洛谷 P3604 美好的每一天 [莫队算法]

    题目背景 时间限制3s,空间限制162MB 素晴らしき日々 我们的情人,不过是随便借个名字,用幻想吹出来的肥皂泡,把信拿去吧,你可以使假戏成真.我本来是无病呻吟,漫无目的的吐露爱情---现在这些漂泊不 ...

  2. Bzoj2038/洛谷P1494 小Z的袜子(莫队)

    题面 Bzoj 洛谷 题解 考虑莫队算法,首先对询问进行分块(分块大小为\(sqrt(n)\)),对于同一个块内的询问,按照左端点为第一关键字,右端点为第二关键字排序.我们统计这个区间内相同的颜色有多 ...

  3. 【洛谷4396/BZOJ3236】[AHOI2013]作业(莫队+分块/树状数组/线段树)

    题目: 洛谷4396 BZOJ3236(权限) 这题似乎BZOJ上数据强一些? 分析: 这题真的是--一言难尽 发现题面里没说权值的范围,怕出锅就写了离散化.后来经过面向数据编程(以及膜神犇代码)知道 ...

  4. 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】

    P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...

  5. 洛谷 P3674 小清新人渣的本愿 [莫队 bitset]

    传送门 题意: 给你一个序列a,长度为n,有Q次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ...

  6. 洛谷2709 小B的询问(莫队)

    题面 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R] ...

  7. 洛谷P5072 [Ynoi2015]盼君勿忘 [莫队]

    传送门 辣鸡卡常题目浪费我一下午-- 思路 显然是一道莫队. 假设区间长度为\(len\),\(x\)的出现次数为\(k\),那么\(x\)的贡献就是\(x(2^{len-k}(2^k-1))\),即 ...

  8. 洛谷P3709 大爷的字符串题(莫队)

    题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...

  9. 洛谷P4462 [CQOI2018]异或序列(莫队)

    打广告->[这里](https://www.cnblogs.com/bztMinamoto/p/9538115.html) 我蠢了…… 如果$a_{l} xor ...a_{r}=k$,那么只要 ...

随机推荐

  1. [JAVA反序列化DEMO]利用RMI进行反序列化一键启动工具

    功能: 命令行启动jar包,用户自定义启动RMI端口.默认内置Apache Commons Collections.只需一键启动即可测试java反序列化漏洞. 启动服务: [root@sevck_v3 ...

  2. Mybatis 内置 Java 类型别名与 typeHandlers

    aliases There are many built-in type aliases for common Java types. They are all case insensitive, n ...

  3. 一个hitbernate配置文件,带几个表(注意mapping);如果连接字符串没有设置utf-8,向insert mysql 会产生乱码(utf8 或 utf-8)

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuratio ...

  4. jquery ajax中error返回错误解决办法

    转自:https://www.jb51.net/article/72198.htm 进入百度搜索此问题,发现有人这么说了一句 Jquery中的Ajax的async默认是true(异步请求),如果想一个 ...

  5. 部署和调优 1.6 vsftp部署和优化-2

    映射个虚拟用户 创建个用户,不让他登录 useradd virftp -s /sbin/nologin 创建存放虚拟用户用户和密码的文件 vim /etc/vsftpd/vsftpd_login 写入 ...

  6. 【Android 多媒体应用】使用MediaRecoder录制,MediaPlayer播放音频数据

    1.MainActivity.java import android.annotation.TargetApi; import android.app.Activity; import android ...

  7. SSH简单搭建

    本项目使用Struts2+spring3+hibernate3: 第一步:引入jar包,具体需要哪些包根据实际情况加入.注意:把jar包导入后需要对所有包Add to Build Path;然后对工程 ...

  8. 使用GSON来生成JSON数据

    第二种方法: 当不需要显示某个属性时,在不需要显示出的属性前加transient关键字即可满足 使用gson来解析 使用gson解析 带日期转换 集合类解析:gson中的数组与java中集合类都是对应 ...

  9. re.findall(?: ) ?:取消优先获取组的权限

  10. c语言中argc和argv

    main函数的参数,解释如下: argc:命令行总的参数的个数,即argv中元素的格式. *argv[ ]:字符串数组,用来存放指向你的字符串参数的指针数组,每一个元素指向一个参数. argv[0]: ...