洛谷P3604 美好的每一天(莫队)
由乃的题还是一如既往的可怕……
先放上原题解
标解:
一个区间可以重排成为回文串,即区间中最多有一个字母出现奇数次,其他的都出现偶数次
发现这个和 类似





这样如果一个区间的 和为
或者
,则这个区间可以重排成为回文串,即回归天空
把每个位置的值变为前缀 和,那么区间
可以回归天空当且仅当
为
或者
即
的异或和
这样用莫队算法,可以做到 的复杂度
然后怎么用莫队?可以参考一下这道题目->异或序列
考虑区间$[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 美好的每一天(莫队)的更多相关文章
- B 洛谷 P3604 美好的每一天 [莫队算法]
题目背景 时间限制3s,空间限制162MB 素晴らしき日々 我们的情人,不过是随便借个名字,用幻想吹出来的肥皂泡,把信拿去吧,你可以使假戏成真.我本来是无病呻吟,漫无目的的吐露爱情---现在这些漂泊不 ...
- Bzoj2038/洛谷P1494 小Z的袜子(莫队)
题面 Bzoj 洛谷 题解 考虑莫队算法,首先对询问进行分块(分块大小为\(sqrt(n)\)),对于同一个块内的询问,按照左端点为第一关键字,右端点为第二关键字排序.我们统计这个区间内相同的颜色有多 ...
- 【洛谷4396/BZOJ3236】[AHOI2013]作业(莫队+分块/树状数组/线段树)
题目: 洛谷4396 BZOJ3236(权限) 这题似乎BZOJ上数据强一些? 分析: 这题真的是--一言难尽 发现题面里没说权值的范围,怕出锅就写了离散化.后来经过面向数据编程(以及膜神犇代码)知道 ...
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- 洛谷 P3674 小清新人渣的本愿 [莫队 bitset]
传送门 题意: 给你一个序列a,长度为n,有Q次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ...
- 洛谷2709 小B的询问(莫队)
题面 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R] ...
- 洛谷P5072 [Ynoi2015]盼君勿忘 [莫队]
传送门 辣鸡卡常题目浪费我一下午-- 思路 显然是一道莫队. 假设区间长度为\(len\),\(x\)的出现次数为\(k\),那么\(x\)的贡献就是\(x(2^{len-k}(2^k-1))\),即 ...
- 洛谷P3709 大爷的字符串题(莫队)
题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...
- 洛谷P4462 [CQOI2018]异或序列(莫队)
打广告->[这里](https://www.cnblogs.com/bztMinamoto/p/9538115.html) 我蠢了…… 如果$a_{l} xor ...a_{r}=k$,那么只要 ...
随机推荐
- MySQL 双主+keepalived 详细文档 M-M+keepalived
1. 操作系统,系统环境,目结结构,用户,权限,日志路径,脚本2. 配置规范化 1.1 操作系统准备 操作系统 Kylin Linux release 3.3.1707 (Core)数据库版本 mys ...
- linux设置支持中文
LANG="zh_CN.UTF-8" #LANG="zh_CN.GB18030" #LANG=en_US.UTF-8 LANGUAGE="zh_CN. ...
- 第十三章 Spring框架的设计理念与设计模式分析(待续)
Spring的骨骼架构 核心组件详解 Spring中AOP的特性详解 设计模式解析之代理模式 设计模式解析之策略模式
- laravel4 composer报错 d11wtq/boris v1.0.10 requires ext-pcntl
laravel4 composer报错 d11wtq/boris v1.0.10 requires ext-pcntl laravel 4.2 用composer 安装任何包都会报这个错,通过谷歌找到 ...
- Don’t panic, it’s just a kernel panic (ZT)
http://blog.kreyolys.com/2011/03/17/no-panic-its-just-a-kernel-panic/ One of the main young sysadmin ...
- leetcode637
层次遍历,计算每一层的节点值,然后求平均值. class Solution { public: vector<double> averageOfLevels(TreeNode* root) ...
- Navicat断网时连不上数据库
最近安装了破解的Navicat,在有网的条件下可以连接本地安装的MySQL数据库,但断网之后就不可以,如下: 于是上网查资料,发现原因为: localhost可以看成是一个域名,在一大部分情况下,它能 ...
- 如何实现1080P延迟低于500ms的实时超清直播传输技术<转>
转载地址:http://www.yunweipai.com/archives/9037.html 最近由于公司业务关系,需要一个在公网上能实时互动超清视频的架构和技术方案.众所周知,视频直播用 CDN ...
- Webrtc服务器搭建<转>
http://blog.csdn.net/zqf_office/article/details/49851209
- css水平垂直居中方法(一)
第五种方法: 首先设置一个div,设置其的width与height,为了方便观察,我定义了div的背景色为red,代码如下: <!doctype html> <html lang=& ...