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$,那么只要 ...
随机推荐
- ASP.NET没有魔法——ASP.NET OAuth、jwt、OpenID Connect
上一篇文章介绍了OAuth2.0以及如何使用.Net来实现基于OAuth的身份验证,本文是对上一篇文章的补充,主要是介绍OAuth与Jwt以及OpenID Connect之间的关系与区别. 本文主要内 ...
- [国嵌攻略][068][tftp网络协议实现]
IP协议结构 UDP协议结构 TFTP协议结构 TFTP端口 读写请求端口: 69 其他请求端口:1024~65535 主程序 /*********************************** ...
- java if与for循环的题
//打印一个4*5的空心长方形 /* for (int i = 0; i < 5;i++ ) { if (i == 0 | i == 4) { ...
- 怎么去掉织梦网站首页带的index.html/index.php
方法1. 1)在空间面板里面找到默认首页设置: 我们是需要去掉index.html,这时我们只需要把index.html这个把它移到最顶级去就行,然后点击确定,在打开网站刷新下,就基本可以解决了! 其 ...
- ThinkPhp_5框架开发【整理】
================================================== ThinkPhp_5心得笔记 ---------------------------------- ...
- asp.net -mvc框架复习(3)-控制器和动作方法的任务分析
using System;using System.Collections.Generic;using System.Linq;using System.Web;//ASP.NET核心命名空间usin ...
- 【问题解决】Eclipse中 ctrl+空格 content assist
改一下你的快捷键设置:window->perferences-->keys--->查找 content assist--->把这个地方改成你想要的就可以了.!
- [知了堂学习笔记]_牵线Eclipse和Tomcat第二篇 —— 安装Tomcat&&添加Tomcat到Eclipse
来了来了~~~~~我们的"织女"--Tomcat来了,牛郎们等急了吧!哈哈! 一.安装Tomcat 下载地址:http://tomcat.apache.org/download-7 ...
- np.array转换为list,嵌套的python list转成一个一维的python list
np.array转换为list 1 meitan = shuju.iloc[start:end, 1:2] zhengqi = shuju.iloc[start:end,2:3] print(type ...
- mybatis传参的几种方式
1,@Param @参考文章 @Select("select s_id id,s_name name,class_id classid from student where s_name= ...