[bzoj4866] [Ynoi2017]由乃的商场之旅
来自FallDream的博客,未经允许,请勿转载,谢谢,
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#define rint register int
#define MN 60000
#define ll long long
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
} map<int,int> mp;
ll ans=,Ans[MN+];
bool b[MN+];
int n,m,now=,dn=,p[],block[MN+],size,L,R,ha[MN+],cnt=,f[MN+],head[MN+];
char st[MN+];
struct ques{int l,r,id;}q[MN+];
struct edge{int to,next;}e[MN*+];
bool cmp(ques x,ques y){return block[x.l]==block[y.l]?x.r<y.r:x.l<y.l;}
inline void ins(int f,int t){if(!t)return;e[++cnt]=(edge){t,head[f]};head[f]=cnt;} inline void Ins(int num,int ad)
{
for(int i=head[ha[num]];i;i=e[i].next)
ans+=f[e[i].to]*ad;
ans+=ad*f[ha[num]];
} int main()
{
n=read();m=read();p[]=;size=sqrt(n);
for(rint i=;i<=n;++i) block[i]=(i-)/size+;
for(rint i=;i<;++i) p[i]=p[i-]<<;
scanf("%s",st+);mp[]=++dn;
for(rint i=;i<=n;++i) ha[i]=ha[i-]^p[st[i]-'a'],!mp[ha[i]]?mp[ha[i]]=++dn:b[i]=;
for(rint j=;j<;++j) ins(,mp[p[j]]);ha[]=;
for(int i=;i<=n;++i)
{
int now=mp[ha[i]];
if(!b[i])for(int j=;j<;++j) ins(now,mp[ha[i]^p[j]]);
ha[i]=now;
}
for(rint i=;i<=m;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q+m+,cmp);L=R=,++f[],++f[ha[]],ans=;
for(rint i=;i<=m;++i)
{
while(R<q[i].r) ++R,Ins(R,),++f[ha[R]];
while(L>q[i].l) --L,Ins(L-,),++f[ha[L-]];
while(L<q[i].l) --f[ha[L-]],Ins(L-,-),++L;
while(R>q[i].r) --f[ha[R]],Ins(R,-),--R;
Ans[q[i].id]=ans;
}
for(int i=;i<=m;++i) printf("%lld\n",Ans[i]);
return ;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define rint register int
#define MN 60000
#define MB 1300
#define ll long long
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
} ll ans=,Ans[MN+],Pre[MN+];
int n,m,now=,dn=,p[],block[MN+],size,R,ha[MN+],tot,rt[MB+];
unsigned short f[<<];
char st[MN+];
struct ques{int l,r,id;}q[MN+];
bool cmp(ques x,ques y){return block[x.l]==block[y.l]?x.r<y.r:x.l<y.l;} inline void Ins(int num,int ad)
{
if(num>n) return;
f[num=ha[num]]+=ad;
for(int i=;i<;++i) f[num^p[i]]+=ad;
} ll Bl(int l,int r)
{
ll ans2=;
for(int i=l;i<=r;++i)
Ins(i-,),ans2+=f[ha[i]];
for(int i=l;i<=r;++i) Ins(i-,-);
return ans2;
} int main()
{
n=read();m=read();p[]=;size=sqrt(*n);tot=(n-)/size+;
for(rint i=;i<=n;++i) block[i]=(i-)/size+;
for(rint i=;i<;++i) p[i]=p[i-]<<;
scanf("%s",st+);
for(rint i=;i<=n;++i) ha[i]=ha[i-]^p[st[i]-'a'];
for(int i=;i<=tot;++i)
{
rt[i]=min(n,i*size);ans=;
for(int j=rt[i];j>rt[i-];--j)
Ins(j,),ans+=f[ha[j-]],Pre[j]=ans;
for(int j=rt[i];j>rt[i-];--j) Ins(j,-);
}
for(rint i=;i<=m;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q+m+,cmp);
for(rint i=,last=;i<=m;++i)
{
if(block[q[i].l]!=last)
{
for(int i=rt[last];i<R;++i) Ins(i,-);
last=block[q[i].l];Ins(R=rt[last],);ans=(++R<=n);
}
if(block[q[i].l]==block[q[i].r]) Ins(rt[last],-),Ans[q[i].id]=Bl(q[i].l,q[i].r),Ins(rt[last],);
else
{
while(R<q[i].r) ++R,Ins(R-,),ans+=f[ha[R]];
ll ans2=;Ins(R,);Ins(rt[last],-);
for(int j=q[i].l;j<=rt[last];++j) ans2+=f[ha[j-]];
Ans[q[i].id]=ans+Pre[q[i].l]+ans2;
Ins(R,-);Ins(rt[last],);
}
}
for(int i=;i<=m;++i) printf("%lld\n",Ans[i]);
return ;
}
把它们揉一起 飞快
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<cmath>
#define rint register int
#define MN 60000
#define MB 1300
#define ll long long
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
} bool b[MN+];
map<int,int> mp;
ll ans=,Ans[MN+],Pre[MN+];
int n,m,now=,dn=,p[],block[MN+],size,R,ha[MN+],tot,rt[MB+],head[MN+],cnt=;
unsigned short f[MN+];
char st[MN+];
struct ques{int l,r,id;}q[MN+];
struct edge{int to,next;}e[MN*+];
bool cmp(ques x,ques y){return block[x.l]==block[y.l]?x.r<y.r:x.l<y.l;}
inline void ins(int f,int t){if(!t)return;e[++cnt]=(edge){t,head[f]};head[f]=cnt;}
inline void Ins(int num,int ad)
{
if(num>n) return;
f[num=ha[num]]+=ad;
for(int i=head[num];i;i=e[i].next) f[e[i].to]+=ad;
} ll Bl(int l,int r)
{
ll ans2=;
for(int i=l;i<=r;++i)
Ins(i-,),ans2+=f[ha[i]];
for(int i=l;i<=r;++i) Ins(i-,-);
return ans2;
} int main()
{
n=read();m=read();p[]=;size=sqrt(*n);tot=(n-)/size+;
for(rint i=;i<=n;++i) block[i]=(i-)/size+;
for(rint i=;i<;++i) p[i]=p[i-]<<;
scanf("%s",st+);mp[]=++dn;
for(rint i=;i<=n;++i) ha[i]=ha[i-]^p[st[i]-'a'],!mp[ha[i]]?mp[ha[i]]=++dn:b[i]=;
for(rint j=;j<;++j) ins(,mp[p[j]]);ha[]=;
for(int i=;i<=n;++i)
{
int now=mp[ha[i]];
if(!b[i])for(int j=;j<;++j) ins(now,mp[ha[i]^p[j]]);
ha[i]=now;
}
for(int i=;i<=tot;++i)
{
rt[i]=min(n,i*size);ans=;
for(int j=rt[i];j>rt[i-];--j)
Ins(j,),ans+=f[ha[j-]],Pre[j]=ans;
for(int j=rt[i];j>rt[i-];--j) Ins(j,-);
}
for(rint i=;i<=m;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q+m+,cmp);
for(rint i=,last=;i<=m;++i)
{
if(block[q[i].l]!=last)
{
for(int i=rt[last];i<R;++i) Ins(i,-);
last=block[q[i].l];Ins(R=rt[last],);ans=(++R<=n);
}
if(block[q[i].l]==block[q[i].r]) Ins(rt[last],-),Ans[q[i].id]=Bl(q[i].l,q[i].r),Ins(rt[last],);
else
{
while(R<q[i].r) ++R,Ins(R-,),ans+=f[ha[R]];
ll ans2=;Ins(R,);Ins(rt[last],-);
for(int j=q[i].l;j<=rt[last];++j) ans2+=f[ha[j-]];
Ans[q[i].id]=ans+Pre[q[i].l]+ans2;
Ins(R,-);Ins(rt[last],);
}
}
for(int i=;i<=m;++i) printf("%lld\n",Ans[i]);
return ;
}
[bzoj4866] [Ynoi2017]由乃的商场之旅的更多相关文章
- BZOJ4866 Ynoi2017由乃的商场之旅(莫队)
显然能重排为回文串相当于出现次数为奇数的字母不超过一个.考虑莫队,问题在于如何统计添加/删除一位的贡献.将各字母出现次数奇偶性看做二进制数,做一个前缀和一个后缀和.在右端添加一位时,更新区间的前缀.后 ...
- 【莫队】bzoj4866: [Ynoi2017]由乃的商场之旅
莫队的一些套路 Description 由乃有一天去参加一个商场举办的游戏.商场派了一些球王排成一行.每个人面前有几堆球.说来也巧,由乃和你 一样,觉得这游戏很无聊,于是决定换一个商场.另一个商场是D ...
- 【BZOJ4866】[YNOI2017] 由乃的商场之旅(莫队)
点此看题面 大致题意: 给你一个字符串,每次给你一段区间,问这段区间内有多少个字符串在重新排列后可以变成一个回文串. 关于莫队 详见这篇博客:莫队算法学习笔记(一)--普通莫队. 关于回文 要使一个字 ...
- bzoj 4866: [Ynoi2017]由乃的商场之旅
设第i个字母的权值为1<<i,则一个可重集合可以重排为回文串,当且仅当这个集合的异或和x满足x==x&-x,用莫队维护区间内有多少对异或前缀和,异或后满足x==x&-x,这 ...
- 「SCOI2014」方伯伯的商场之旅 解题报告
「SCOI2014」方伯伯的商场之旅 我一开始的想法会被两个相同的集合位置去重给搞死,不过应该还是可以写的,讨论起来老麻烦. 可以先钦定在\(1\)号点集合,然后往后调整一部分. 具体一点,通过前缀和 ...
- 「SCOI2014」方伯伯的商场之旅
「SCOI2014」方伯伯的商场之旅 题目描述 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 \(i\) 的人面前的第 \(j\) 堆的石 ...
- [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)
3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 449 Solved: 254[Submit][Sta ...
- 洛谷P3286 [SCOI2014]方伯伯的商场之旅
题目:洛谷P3286 [SCOI2014]方伯伯的商场之旅 思路 数位DP dalao说这是数位dp水题,果然是我太菜了... 自己是不可能想出来的.这道题在讲课时作为例题,大概听懂了思路,简单复述一 ...
- 【bzoj3598】: [Scoi2014]方伯伯的商场之旅
Description 方伯伯有一天去参加一个商场举办的游戏.商场派了一些工作人员排成一行.每个人面前有几堆石子.说来也巧,位置在 i 的人面前的第 j 堆的石子的数量,刚好是 i 写成 K 进制后的 ...
随机推荐
- Mysql数据库的触发程序
/** **创建表 */ CREATE TABLE test1(a1 INT); CREATE TABLE test2(a2 INT); CREATE TABLE test3(a3 INT NOT N ...
- poj2029 Get Many Persimmon Trees
http://poj.org/problem?id=2029 单点修改 矩阵查询 二维线段树 #include<cstdio> #include<cstring> #inclu ...
- highcharts 具体参数详解
<script type="text/javascript" src="js/jquery.min.js"></script> < ...
- 如何书写高效的css样式
如何书写高效的css样式? 有以下四个关键要素: 1.高效的css 2.可维护的css 3.组件化的css 4.hack-free css 书写高效的css: 1.使用外联样式替代行间样式或内嵌样式 ...
- JAVA_SE基础——47.接口
如果一个抽象类中的所有方法都是抽象的,则可以将这个类用另一种方法来定义,即接口~ 在定义接口时,需要用interface关键字来声明,具体实例如code1 接口的定义格式:interface 接口名{ ...
- 深度学习之 GAN 进行 mnist 图片的生成
深度学习之 GAN 进行 mnist 图片的生成 mport numpy as np import os import codecs import torch from PIL import Imag ...
- Python模块 - paramiko
paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能.这是一个第三方的软件包,使用之前需要安装. 1 基于用户名和密码的 sshclient 方式登录 # 建立一个s ...
- PyMySQL模块的使用
PyMySQL介绍 PyMySQL是在Python3.x版本中用于连接MySQL服务器的一个库,Python2系列中则使用mysqldb.Django中也可以使用PyMySQL连接MySQL数据库. ...
- Mysql官方文档翻译系列14.18--MySql备份与恢复
原文链接: (https://dev.mysql.com/doc/refman/5.7/en/innodb-backup-recovery.html) The key to safe database ...
- AOP及专有名词通俗解答
AOP面向切面编程,是一种编程思想,并不是Spring专有,Spring是封装代理模式完成,之前的博客中也写到了关于AOP的文章,Filter和代理,请见<以此之长,补彼之短----AOP(Fi ...