题目背景

时间限制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. ubuntu sendmail配置发送邮件

    ubuntu中sendmail函数可以很方便的发送邮件,ubuntu sendmail先要安装两个包. 必需安装的两个包: 代码  sudo apt-get install sendmail sudo ...

  2. vue 开发2017年变化回顾及2018年展望

    vue.js 变化 从 github 的发布记录我们可以看到2017年 vue.js 的第一个发布为 v2.1.9,最后一个为 v2.5.13,主要发布小版本 2.2~2.5.这些发布提升了vue 与 ...

  3. jsp页面中的$(param.xxx)

    $(param.user)相当于<%=request.getParameter("user")%> $(paramValues.favorites[0])相当于< ...

  4. RequireJS(一)

    RequireJS: RequireJS中文网:http://www.requirejs.cn/ 解决HTML引入大量js文件导致的问题: 首先是加载的时候,浏览器会停止网页渲染,加载文件越多,网页失 ...

  5. LED服务总结

    简单的程序总结 一个简单的用于控制LED屏幕的小程序,用到的一个常识 LED服务开发总结 系统运行截图   系统功能说明: 1.ServerStrack服务,提供前台访问. 2.动态库调用,用于信息转 ...

  6. FORTH基础

    body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...

  7. C语言知识点总结

    本文采用思维导图的方式撰写,更好的表述了各知识点之间的关系,方便大家理解和记忆.这个总结尚未包含C语言数据结构与算法部分,后续会陆续更新出来,文中有漏掉的知识点,还请大家多多指正.

  8. mysql中能够使用索引的典型场景

    mysql 演示数据库:http://downloads.mysql.com/docs/sakila-db.zip 匹配全值 explain select * from rental where re ...

  9. OpenCv函数学习(一)

    Intel Image Processing Library (IPL) typedef struct _IplImage { int nSize; /* IplImage大小 */ int ID; ...

  10. JAVA中利用反射机制进行对象和Map相互转换的方法

    JAVA的反射机制主要作用是用来访问对象的属性.方法等等.所以,JAVA中对象和Map相互转换可以利用JAVA的反射机制来实现.例子如下: 一.对象转Map的方法 public static Map& ...