[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 进制后的 ...
随机推荐
- java连接jdbc Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by defa
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp_db","root",& ...
- JAVA_SE基础——5.第一个Java程序HelloWorld&注释的应用
配置完JDK&环境变量后,我们就可以开始写程序了,那么程序怎么写呢,用什么工具呢,我建议 为了方便学习,我们最好在一个磁盘下建立一个专门的文件来写java程序,比如就在D盘下建立一个名为&qu ...
- C#之Socket通信
0.虽然之前在项目中也有用过Socket,但始终不是自己搭建的,所以对Server,Clinet端以及心跳,断线重连总没有很深入的理解,现在自己搭建了一遍加深一下理解. 服务端使用WPF界面,客户端使 ...
- 谈谈ASP.NET Core中的ResponseCaching
前言 前面的博客谈的大多数都是针对数据的缓存,今天我们来换换口味.来谈谈在ASP.NET Core中的ResponseCaching,与ResponseCaching关联密切的也就是常说的HTTP缓存 ...
- js实现图片(高度不确定)懒加载
最近一直在弄广告页,由于广告页几乎都是图片拼凑起来的,为了减少服务器压力和带宽,采用图片懒加载方式,但是我们的图片高度又不确定,所以我在网上下载了echo.js自己改了一下. 大体思路是:让首页先加载 ...
- javascript中获取dom元素的高度和宽度
javascript中获取dom元素高度和宽度的方法如下: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网 ...
- Linux知识积累(6) 系统目录及其用途
linux系统常见的重要目录以及各个目作用:/ 根目录.包含了几乎所有的文件目录.相当于中央系统.进入的最简单方法是:cd /./boot引导程序,内核等存放的目录.这个目录,包括了在引导过程中所必需 ...
- bootstrap表格 之多选数据的获取
使用表格的时候经常会用到多选的功能,比较常用,下面写一个小Dome记录一下 如下:单击批量删除按钮之后,需要获取选中行数据,传值到后台进行处理 一.获取选择行的数据 btnplDel是按钮id:tab ...
- C#微信公众号——自定义菜单
自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单.一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替.自定义菜单的介绍,可以看官方开发文档http://mp. ...
- js中的caller属性和callee属性
应该用"属性"来称呼caller和callee,而不是方法. caller:返回调用当前函数的函数的引用.a调用b,则返回a(a是boss,因为a把b叫过去干活了): callee ...