[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 进制后的 ...
随机推荐
- 将数组写入Plist文件中
-(void)writeToPlist:(NSArray *)uploadingfiles Name:(NSString *)name { NSMutableArr ...
- Ubuntu Desktop 16.04 LTS 下成功配置Jupyter的两个python内核版本(2.7x,3.5x)
Ubuntu Desktop 16.04 LTS 安装好系统默认就有python两个不同版本(2.7.12和3.5.2) 现在来熟悉一下jupyter的对python这两个不同python版本的内核 ...
- JavaScript 动态显示当前时间
代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <tit ...
- 第二章 Idea搭建maven
第二章 Idea搭建maven 1.配置Maven的环境变量 a.首先我们去maven官网下载Maven程序,解压到安装目录,如图所示: b.配置M2_HOME(MAVEN_HOME)的环境变量,然后 ...
- machine learning 之 logistic regression
整理自Adrew Ng 的 machine learning课程week3 目录: 二分类问题 模型表示 decision boundary 损失函数 多分类问题 过拟合问题和正则化 什么是过拟合 如 ...
- mysql 索引学习--多条件等值查询,顺序不同也能应用联合索引啦
以前学习这一块的时候,是说:假设建立了联合索引a+b,那么查询语句也一定要是这个顺序才能应用该索引. 那么实际是怎样呢,经过mysql这么多次版本升级,相信mysql已经给我们做了某些优化. 下面是我 ...
- SpringMVC(九):SpringMVC 处理输出模型数据之ModelAndView
Spring MVC提供了以下几种途径输出模型数据: 1)ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据: 2)Map及Model:处理方法 ...
- Spark:导入数据到oracle
方案一: //overwrite JdbcDialect fitting for Oracle val OracleDialect = new JdbcDialect { override def c ...
- scrapy的命令行
scrapy --help 列出帮助信息以及常用命令scrapy version 列出scrapy版本scrapy version -v 列出详细的scrapy版本以及各组件信息 scrapy sta ...
- 闭包(closure)
大牛的讲解,点击 我们首先需要有作用域的概念,点击 那么什么是闭包? 官方的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 广义上的 ...