题目背景

时间限制3s,空间限制162MB

素晴らしき日々

我们的情人,不过是随便借个名字,用幻想吹出来的肥皂泡,把信拿去吧,你可以使假戏成真。我本来是无病呻吟,漫无目的的吐露爱情---现在这些漂泊不定的鸟儿有地方栖息了,你可以从信里看出来。拿去吧---由于不是出自真心,话就说得格外动听,拿去吧,就这么办吧...

由于世界会在7月20日完结,作为救世主,间宫卓司要在19日让所有人回归天空

现在已经是19日傍晚,大家集合在C栋的天台上,一共n个人

在他们面前,便是终之空,那终结的天空

题目描述

回归天空是一件庄重的事情,所以卓司决定让大家分批次进行,给每个人给了一个小写字母'a'->'z'作为编号

一个区间的人如果满足他们的编号重排之后可以成为一个回文串,则他们可以一起回归天空,即这个区间可以回归天空

由于卓司是一个喜欢妄想的人,他妄想了m个区间,每次他想知道每个区间中有多少个子区间可以回归天空

因为世界末日要来了,所以卓司的信徒很多

输入输出格式

输入格式:

第一行两个数n,m

之后一行一个长为n的字符串,代表每个人的编号

之后m行每行两个数l,r代表每次卓司妄想的区间

输出格式:

m行,每行一个数表示答案

输入输出样例

输入样例#1:

6 6
zzqzzq
1 6
2 4
3 4
2 3
4 5
1 1
输出样例#1:

16
4
2
2
3
1

说明

对于10%的数据,n,m<=100

对于30%的数据,n,m<=2000

对于100%的数据,n,m<=60000

字符集大小有梯度

在大家回归天空之后,彩名露出了阴冷的笑容


先奉上O(n2) 30分骗分

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,Q,l,r;
char c[N];
int a[N][N],s[N][N],cnt[],now;
void ini(){
for(int i=;i<=n;i++){
memset(cnt,,sizeof(cnt));now=;
for(int j=i;j<=n;j++){
if(cnt[c[j]]%==) now++;
else now--;
cnt[c[j]]++;
if((j-i+)%==&&now==) a[i][j]=;
if((j-i+)%==&&now==) a[i][j]=;
s[i][j]=s[i][j-]+a[i][j];
//printf("hi %d %d %d %d\n",i,j,a[i][j],s[i][j]);
}
}
}
void solve(int l,int r){
int ans=;
for(int i=l;i<=r;i++) ans+=s[i][r]-s[i][i-];
printf("%d\n",ans);
}
int main(int argc, const char * argv[]) {
n=read();Q=read();
scanf("%s",c+);
ini();
while(Q--){
l=read();r=read();
solve(l,r);
}
return ;
}

标解:

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

发现这个和  类似





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

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

 即  的异或和

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

怎么用莫队呢?去请教了__stdcall

考虑[l,r]—>[l,r+1],就是要找出这个区间里有几个前缀xor满足 a[r+1]^它 =0或(1<<x)

那么用一个桶c存起来 更新答案加上c[a[r+1]^(1<<x)]和c[a[r+1]]就行了

有个细节,[l,r]对应的桶中应该是[l-1,r]的a

然后内存原因c用short

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=6e4+,M=(<<)+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,Q,a[N],bl,pos[N];
char s[N];
struct ques{
int l,r,id;
bool operator <(const ques &a)const{
return pos[l]==pos[a.l]?r<a.r:pos[l]<pos[a.l];
}
}q[N];
unsigned short c[M];
int ans,anss[N];
inline void add(int x){//printf("add %d %d\n",x,a[x]);
ans+=c[a[x]];
for(int i=;i<;i++) ans+=c[a[x]^(<<i)];
c[a[x]]++;
}
inline void del(int x){
c[a[x]]--;
ans-=c[a[x]];
for(int i=;i<;i++) ans-=c[a[x]^(<<i)];
}
void solve(){
sort(q+,q++Q);
c[]++;
int l=,r=;
for(int i=;i<=Q;i++){//printf("Q %d %d %d\n",q[i].l,q[i].r,q[i].id);
while(r<q[i].r) r++,add(r);//printf("hi %d %d %d\n",l,r,ans);
while(r>q[i].r) del(r),r--;//printf("hi %d %d %d\n",l,r,ans);
while(l<q[i].l) del(l-),l++;//printf("hi %d %d %d\n",l,r,ans);
while(l>q[i].l) l--,add(l-);//printf("hi %d %d %d\n",l,r,ans);
anss[q[i].id]=ans;
}
for(int i=;i<=Q;i++) printf("%d\n",anss[i]);
}
int main(int argc, const char * argv[]) {
n=read();Q=read();
scanf("%s",s+);
bl=sqrt(n);
for(int i=;i<=n;i++) a[i]=(<<(s[i]-'a'))^a[i-],pos[i]=(i-)/bl+;
for(int i=;i<=Q;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
solve();
return ;
}

怎么卡常也还是70分

//
// main.cpp
// BB
//
// Created by Candy on 2017/2/2.
// Copyright © 2017年 Candy. All rights reserved.
//
#pragma GCC optimize("O2") #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=6e4+,M=(<<)+;
inline int read(){
char c=getchar();register int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,Q,a[N],bl,pos[N],bit[];
char s[N];
struct ques{
int l,r,id;
bool operator <(const ques &a)const{
return pos[l]==pos[a.l]?r<a.r:pos[l]<pos[a.l];
}
}q[N];
unsigned short c[M];
int ans,anss[N];
inline void add(int x){//printf("add %d %d\n",x,a[x]);
ans+=c[a[x]]++;
for(register int i=;i<;i++) ans+=c[a[x]^bit[i]];
}
inline void del(int x){
ans-=--c[a[x]];
for(register int i=;i<;i++) ans-=c[a[x]^bit[i]];
}
inline void solve(){
for(int i=;i<;i++) bit[i]=<<i;
sort(q+,q++Q);
c[]++;
int l=,r=;
for(int i=;i<=Q;i++){//printf("Q %d %d %d\n",q[i].l,q[i].r,q[i].id);
while(r<q[i].r) add(++r);//printf("hi %d %d %d\n",l,r,ans);
while(r>q[i].r) del(r--);//printf("hi %d %d %d\n",l,r,ans);
while(l<q[i].l) del(l-),l++;//printf("hi %d %d %d\n",l,r,ans);
while(l>q[i].l) add(--l-);//printf("hi %d %d %d\n",l,r,ans);
anss[q[i].id]=ans;
}
for(int i=;i<=Q;i++) printf("%d\n",anss[i]);
}
int main(int argc, const char * argv[]) {
n=read();Q=read();
scanf("%s",s+);
bl=sqrt(n);
for(int i=;i<=n;i++) a[i]=(<<(s[i]-'a'))^a[i-],pos[i]=(i-)/bl+;
for(int i=;i<=Q;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
solve();
return ;
}

卡常后很丑

B 洛谷 P3604 美好的每一天 [莫队算法]的更多相关文章

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

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

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

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

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

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

  4. 洛谷P3604 美好的每一天(莫队)

    传送门 由乃的题还是一如既往的可怕…… 先放上原题解 标解: 一个区间可以重排成为回文串,即区间中最多有一个字母出现奇数次,其他的都出现偶数次 发现这个和  类似 这样如果一个区间的  和为  或者  ...

  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. c语言sizeof用法(32位机)

  2. UEP-多任务

    打开多任务 Function testTabTask(){ openTabTask(","多任务测试",$$pageContextPath+"/componen ...

  3. Dora.Interception, 一个为.NET Core度身打造的AOP框架[3]:Interceptor的注册

    在<不一样的Interceptor>中我们着重介绍了Dora.Interception中最为核心的对象Interceptor,以及定义Interceptor类型的一些约定.由于Interc ...

  4. VS2008 如何将Release版本设置可以调试的DEBUG版本

    VS2008 如何将Release版本设置可以调试的DEBUG版本 只需设置三个部分: 项目->属性->C/C++->General->Debug Information Fo ...

  5. JSP学习总结

    1. 为什么需要jsp?  Servlet对于逻辑处理是非常方便的,但是对于页面的展现是非常麻烦的.JSP的诞生是为了解决Servlet页面展现麻烦的问题的. 2. JSP的特点:     Jsp页面 ...

  6. JVM GC杂谈之理论入门

    GC杂谈之理论入门 JVM堆布局介绍 ​ JVM堆被划分成两个不同的区域:新生代 ( Young ).老年代 ( Old ).新生代 ( Young ) 又被划分为三个区域:Eden.From Sur ...

  7. 自己动手实现一个简单的JSON解析器

    1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 ...

  8. HTML 5 <canvas> 标签

    <!DOCTYPE HTML> <html> <body> <canvas id="myCanvas">your browser d ...

  9. 主页面刷新 illegalStateException:stream

    其实是:jsonmappingexception:no serializer found for class 由于后台错误堆栈打印很快,只看到illegalStateException:stream ...

  10. linux_sudo命令

    sudo 为了收拾su命令的烂摊子 普通用户要切换root,必须要知道root密码,那么相当于人人都有了核按钮,那是绝对不允许的 用su切换到root,无法对是谁要求root权限的身份进行控制,拿到r ...