传送门

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

先放上原题解

标解:

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

发现这个和  类似

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

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

 即  的异或和

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

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

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

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

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 inline int read(){
 8     #define num ch-'0'
 9     char ch;bool flag=0;int res;
10     while(!isdigit(ch=getchar()))
11     (ch=='-')&&(flag=true);
12     for(res=num;isdigit(ch=getchar());res=res*10+num);
13     (flag)&&(res=-res);
14     #undef num
15     return res;
16 }
17 char sr[1<<21],z[20];int C=-1,Z;
18 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
19 inline void print(int x){
20     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
21     while(z[++Z]=x%10+48,x/=10);
22     while(sr[++C]=z[Z],--Z);sr[++C]='\n';
23 }
24 const int N=60005,M=(1<<26)+5;
25 int a[N],rt[N],l,r,n,m,bl;char s[N];
26 struct node{
27     int l,r,id;
28     inline bool operator <(const node b)const
29     {
30         if(rt[l]!=rt[b.l]) return l<b.l;
31         return rt[l]&1?r<b.r:r>b.r;
32     }
33 }q[N];
34 unsigned short c[M];
35 int ans[N],ansn;
36 inline void add(int x){
37     ansn+=c[a[x]];
38     for(int i=0;i<26;++i) ansn+=c[a[x]^(1<<i)];
39     ++c[a[x]];
40 }
41 inline void del(int x){
42     --c[a[x]];
43     ansn-=c[a[x]];
44     for(int i=0;i<26;++i) ansn-=c[a[x]^(1<<i)];
45 }
46 int main(){
47     n=read(),m=read(),bl=sqrt(n);
48     scanf("%s",s+1);
49     for(int i=1;i<=n;++i) a[i]=(1<<(s[i]-'a'))^a[i-1],rt[i]=(i-1)/bl+1;
50     for(int i=1;i<=m;++i)
51     q[i].l=read()-1,q[i].r=read(),q[i].id=i;
52     sort(q+1,q+1+m);
53     l=0,r=0,c[0]=1;
54     for(int i=1;i<=m;++i){
55         while(l>q[i].l) add(--l);
56         while(r<q[i].r) add(++r);
57         while(l<q[i].l) del(l++);
58         while(r>q[i].r) del(r--);
59         ans[q[i].id]=ansn;
60     }
61     for(int i=1;i<=m;++i) print(ans[i]);
62     Ot();
63     return 0;
64 }

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

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 inline int read(){
 8     #define num ch-'0'
 9     char ch;bool flag=0;int res;
10     while(!isdigit(ch=getchar()))
11     (ch=='-')&&(flag=true);
12     for(res=num;isdigit(ch=getchar());res=res*10+num);
13     (flag)&&(res=-res);
14     #undef num
15     return res;
16 }
17 char sr[1<<21],z[20];int C=-1,Z;
18 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
19 inline void print(int x){
20     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
21     while(z[++Z]=x%10+48,x/=10);
22     while(sr[++C]=z[Z],--Z);sr[++C]='\n';
23 }
24 const int N=60005,M=(1<<26)+5;
25 int a[N],b[N],rt[N],l,r,n,m,bl,ver[N*30],Next[N*30],head[N],tot;char s[N];
26 struct node{
27     int l,r,id;
28     inline bool operator <(const node b)const
29     {
30         if(rt[l]!=rt[b.l]) return l<b.l;
31         return rt[l]&1?r<b.r:r>b.r;
32     }
33 }q[N];
34 unsigned short c[M];
35 int ans[N],ansn;
36 inline void addedge(int u,int v){
37     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
38 }
39 inline void add(int x){
40     for(int i=head[a[x]];i;i=Next[i]) ansn+=c[ver[i]];
41     ++c[a[x]];
42 }
43 inline void del(int x){
44     --c[a[x]];
45     for(int i=head[a[x]];i;i=Next[i]) ansn-=c[ver[i]];
46 }
47 int main(){
48     //freopen("testdata.in","r",stdin);
49     n=read(),m=read(),bl=sqrt(n);
50     scanf("%s",s+1);
51     for(int i=1;i<=n;++i) b[i]=a[i]=(1<<(s[i]-'a'))^a[i-1],rt[i]=i/bl;
52     sort(b,b+1+n);
53     int k=unique(b,b+1+n)-b;
54     for(int i=0;i<k;++i){
55         for(int j=0;j<26;++j){
56             int t=b[i]^(1<<j);
57             int y=lower_bound(b,b+k,t)-b;
58             if(b[y]==t) addedge(i,y);
59         }
60         addedge(i,i);
61     }
62     for(int i=1;i<=n;++i) a[i]=lower_bound(b,b+k,a[i])-b;
63     for(int i=1;i<=m;++i)
64     q[i].l=read()-1,q[i].r=read(),q[i].id=i;
65     sort(q+1,q+1+m);
66     l=0,r=0,c[0]=1;
67     for(int i=1;i<=m;++i){
68         while(l>q[i].l) add(--l);
69         while(r<q[i].r) add(++r);
70         while(l<q[i].l) del(l++);
71         while(r>q[i].r) del(r--);
72         ans[q[i].id]=ansn;
73     }
74     for(int i=1;i<=m;++i) print(ans[i]);
75     Ot();
76     return 0;
77 }

转载于:https://www.cnblogs.com/bztMinamoto/p/9538436.html

洛谷P3604 美好的每一天(莫队)相关推荐

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

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

  2. YBTOJ洛谷P4074:糖果公园(树上莫队)

    文章目录 解析 update: 代码 所谓树上莫队,就是在树上的莫队 (逃) 传送门 解析 似乎就是树上的这道题 考虑如何转化为序列问题呢? 考虑dfs序 但是又一个问题... 似乎这条链的dfs序不 ...

  3. 洛谷P5072 [YNOI2015]盼君勿忘 莫队+unordered_set+毒瘤卡常

    在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘 ...

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

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

  5. DP【洛谷P2134】 百日旅行

    [洛谷P2134] 百日旅行 题目背景 重要的不是去哪里,而是和你在一起.--小红 对小明和小红来说,2014年7月29日是一个美好的日子.这一天是他们相识100天的纪念日. (小明:小红,感谢你2场 ...

  6. [洛谷]CON1466 洛谷2017春节联欢赛 Hello Dingyou题解 Bzoj4763雪辉

    题目来源:https://www.luogu.org/contest/show?tid=1466 创建时间:2017/3/13 18:33 镇楼图:       猜猜她是谁~ 解题思路: 春节居然也有 ...

  7. 我的洛谷冬日绘板计划

    我为什么要画这个? 首先,这是一只金色的企鹅--不是鸭子啦! 金企鹅(JQE)是我的一个学长,从我走上oi这条路开始,他就一直在给予我极大的帮助. 可是oi的美好时光流逝得太快,现在他已经高三了,成为 ...

  8. 洛谷 T284709 怨念(resent)

    PS:如果读过题了可以跳过题目描述直接到题解部分 提交链接:洛谷 T284709 怨念(resent) 题目 题目背景 "结束了."dlh眼睁睁地看着右下角的时间到达13:00.屏 ...

  9. 【LGR-142-Div.4】洛谷入门赛 #13 考后分析与题解

    洛谷入门赛 #Round 13 比赛分析与总结 T1 魔方 题目背景 题目描述 输入格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 提示 数据规模与约定 分析 AC代码 注意 T2 教学楼 ...

  10. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

最新文章

  1. NanoPi NEO Air使用十五:使用V4L2驱动USB摄像头
  2. Android开发--Input/OutputStream操作
  3. Spark任务提交底层原理
  4. 三级工作台抽奖出啥_【早早聊】如何落地一体化运营工作台
  5. Java接口回调机制
  6. OpenCV cv :: UMat与DirectX9ex曲面的互操作性的实例(附完整代码)
  7. java二叉树 最大值_leetcode刷题笔记-654. 最大二叉树(java实现)
  8. 【bzoj4025】二分图 LCT
  9. [1] SDK Tools安装
  10. 后台开发(3)---对软件架构的一些思维脑图整理
  11. 如何区分同一Class的不同实例对象
  12. 蓝桥杯练习题(二):Python组之基础练习三十题
  13. 深入浅出mysql第三版pdf百度云,工作感悟
  14. DB2 sqlCode错误信息
  15. hairline!ios实现边框0.5px
  16. OneNet平台创建应用
  17. ML Hyperlink
  18. 如何让电脑计算机d盘布局,创建MSR分区,解决“由于用户电脑存在一个不支持的用于UEFI固件的硬盘布局,因此系统无法安装”...
  19. vmware 14 安装centOS 7时,出现Network boot from Intel E1000
  20. 程序员必备的6款工具软件,炒鸡实用!

热门文章

  1. ubantu apt命令失败
  2. 机器学习项目实战——集成预测政治献金
  3. php生成pdf中文断码_php在线生成pdf中文乱码完美解决“ | 学步园
  4. 访问请转到 http://hi.baidu.com/yuyu8848
  5. python游戏开发(贪吃蛇游戏、五子棋游戏、大球吃小球游戏)
  6. 虎胆龙威5java7723,汉米尔顿腕表联手《虎胆龙威5》再度演绎热血豪情
  7. 云计算基础1-云计算时代的发展-天翼云电脑
  8. 砂糖橘文案:水果砂糖橘的文案,水果文案砂糖橘
  9. SEO-老域名的选择
  10. FLEXPART安装笔记,ubantu,grib_api,eccodes,NetCDF