B 洛谷 P3604 美好的每一天 [莫队算法]
题目背景
时间限制3s,空间限制162MB
素晴らしき日々
我们的情人,不过是随便借个名字,用幻想吹出来的肥皂泡,把信拿去吧,你可以使假戏成真。我本来是无病呻吟,漫无目的的吐露爱情---现在这些漂泊不定的鸟儿有地方栖息了,你可以从信里看出来。拿去吧---由于不是出自真心,话就说得格外动听,拿去吧,就这么办吧...
由于世界会在7月20日完结,作为救世主,间宫卓司要在19日让所有人回归天空
现在已经是19日傍晚,大家集合在C栋的天台上,一共n个人
在他们面前,便是终之空,那终结的天空
题目描述
回归天空是一件庄重的事情,所以卓司决定让大家分批次进行,给每个人给了一个小写字母'a'->'z'作为编号
一个区间的人如果满足他们的编号重排之后可以成为一个回文串,则他们可以一起回归天空,即这个区间可以回归天空
由于卓司是一个喜欢妄想的人,他妄想了m个区间,每次他想知道每个区间中有多少个子区间可以回归天空
因为世界末日要来了,所以卓司的信徒很多
输入输出格式
输入格式:
第一行两个数n,m
之后一行一个长为n的字符串,代表每个人的编号
之后m行每行两个数l,r代表每次卓司妄想的区间
输出格式:
m行,每行一个数表示答案
输入输出样例
6 6
zzqzzq
1 6
2 4
3 4
2 3
4 5
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 美好的每一天 [莫队算法]的更多相关文章
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- Bzoj2038/洛谷P1494 小Z的袜子(莫队)
题面 Bzoj 洛谷 题解 考虑莫队算法,首先对询问进行分块(分块大小为\(sqrt(n)\)),对于同一个块内的询问,按照左端点为第一关键字,右端点为第二关键字排序.我们统计这个区间内相同的颜色有多 ...
- 【洛谷4396/BZOJ3236】[AHOI2013]作业(莫队+分块/树状数组/线段树)
题目: 洛谷4396 BZOJ3236(权限) 这题似乎BZOJ上数据强一些? 分析: 这题真的是--一言难尽 发现题面里没说权值的范围,怕出锅就写了离散化.后来经过面向数据编程(以及膜神犇代码)知道 ...
- 洛谷P3604 美好的每一天(莫队)
传送门 由乃的题还是一如既往的可怕…… 先放上原题解 标解: 一个区间可以重排成为回文串,即区间中最多有一个字母出现奇数次,其他的都出现偶数次 发现这个和 类似 这样如果一个区间的 和为 或者 ...
- 洛谷 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$,那么只要 ...
随机推荐
- DataURL与File,Blob,canvas对象之间的互相转换的Javascript
canvas转换为dataURL (从canvas获取dataURL) var dataurl = canvas.toDataURL('image/png'); var dataurl2 = canv ...
- 免费V P N获取方式
给需要加速器链接国外网站的朋友, 打开网址:http://miaoaff.com/reg.php?id=204250: 用一个邮箱注册,就会得到一个免费的vpn软件账号(包含300M流量时间永久): ...
- .29-浅析webpack源码之Resolver.prototype.resolve
在上一节中,最后返回了一个resolver,本质上就是一个Resolver对象: resolver = new Resolver(fileSystem); 这个对象的构造函数非常简单,只是简单的继承了 ...
- JavaScript八张思维导图—编程风格
JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...
- Version 1.7.0_80 of the JVM is not suitable for this product.Version: 1.8 or greater is required.
Eclipse启动失败,设置eclipse启动jdk有2种方法 第一种: 直接安装eclipse对应的jdk版本,并设置环境变量 第二种: 修改eclipse配置文件eclipse.ini 在plug ...
- 主题:Windows系统服务器磁盘挂载
可能很多人发现VPS重装之后D盘.E盘不见了,其实并没有不见只是磁盘未挂载,下面由小编来为大家讲讲如何挂载磁盘 远程登录服务器后,桌面上只有一个回收站的,我们在桌面空白处右键属性-->桌面--& ...
- Java数据持久层框架 MyBatis之API学习五(Mapper XML 文件)
对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...
- Java进阶篇(四)——Java异常处理
程序中总是存在着各种问题,为了使在程序执行过程中能正常运行,使用Java提供的异常处理机制捕获可能发生的异常,对异常进行处理并使程序能正常运行.这就是Java的异常处理. 一.可捕获的异常 Java中 ...
- excel生成sql语句
很多时候,我们想把excel中数据导入到数据库中. 方法有很多种,比如直接拷贝然后黏贴进编辑状态的框中,这种情况有个弊端,就是excel中每列的数据必须和数据库中一一对应,这个很难,基本上不太可能,数 ...
- zabbix自动清理30天前的数据
转:http://www.361way.com/delete-zabbix-histroy-data/3826.html zabbix属于一个细度化的监控工具,其入库数据随着细度的增加相应的入库数据量 ...