[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 进制后的 ...
随机推荐
- 标准C++类std::string的内存共享和Copy-On-Write(写时拷贝)
标准C++类std::string的内存共享,值得体会: 详见大牛:https://www.douban.com/group/topic/19621165/ 顾名思义,内存共享,就是两个乃至更多的对象 ...
- Java中RuntimeException和Exception的区别
[TOC] 1. 引入RuntimeException public class RuntimeException { public static void main(String[] args) { ...
- MariaDB/MySQL存储过程和函数
本文目录:1.创建存储过程.函数 1.1 存储过程的IN.OUT和INOUT2.修改和删除存储过程.函数3.查看存储过程.函数信息 在MySQL/MariaDB中,存储过程(stored proced ...
- IT学习逆袭的新模式,全栈实习生,不8000就业不还实习费
大家好: 我是马伦,也就是多年耕耘在IT培训一线的老马.老马一直怀揣普惠教育梦想初心,一直为莘莘学子能获得高质量的IT教育服务而奋斗. 之前老马在IT培训机构任职讲师多年,也有丰富的教学管理经验.接触 ...
- EasyUI 中easyui-textbox和easyui-searchbox文本框的点击事件。
html: <input id="txtsearch" class="easyui-textbox" data-options="buttonT ...
- xxe漏洞检测及代码执行过程
这两天看了xxe漏洞,写一下自己的理解,xxe漏洞主要针对webservice危险的引用的外部实体并且未对外部实体进行敏感字符的过滤,从而可以造成命令执行,目録遍历等.首先存在漏洞的web服务一定是存 ...
- 利用封装、继承对Java代码进行优化
注:本文实例分别可以在oldcastle(未优化的代码)和newcastle(优化后的代码)中查看,网址见文末 城堡游戏: 城堡中有多个房间,用户通过输入north, south, east, wes ...
- 回收 PV - 每天5分钟玩转 Docker 容器技术(152)
当 PV 不再需要时,可通过删除 PVC 回收. 当 PVC mypvc1 被删除后,我们发现 Kubernetes 启动了一个新 Pod recycler-for-mypv1,这个 Pod 的作用就 ...
- 【JavaScript中typeof、toString、instanceof、constructor与in】
JavaScript中typeof.toString.instanceof.constructor与in JavaScript 是一种弱类型或者说动态语言.这意味着你不用提前声明变量的类型,在程序运行 ...
- Angular 学习笔记 ( CDK - Layout )
简单说就是 js 的 media query. 1. BreakpointObserver const layoutChanges = this.breakpointObserver.observe ...