【BZOJ2821】作诗 题解(分块+前缀和)
前言:世间还有这么卡常的题……
------------------
题目大意:给定长度为$n$的序列${a_i}$。有$m$次询问,问$[l,r]$内出现正偶数次的数字有多少个。
这题跟蒲公英有些相似,不同的是这题特别卡常……
设$sum[i][j]$表示前$i$块内$j$出现的次数,$ans[i][j]$表示块$i$到$j$的答案。
主要的问题是怎么在$O(n \sqrt n)$内进行预处理。我们采用“边扫边求”的方式来进行处理,扫的时候开一个桶,注意不要重复统计。对于$ans[i][j]$,我们有:
设$t$为块$i$到$j-1$内数$k$出现的次数。
1.如果$t$是奇数并且$bucket[k]$也是奇数,那么$ans[i][j]++$。
2.如果$t$是偶数并且$bucket[k]$是奇数,那么$ans[i][j]--$。
剩下的就跟蒲公英的处理差不多了。注意不要使用memset!!!!!!(血与泪的教训QAQ)
代码:
//求l到r中出现偶次的数字的个数
#include<bits/stdc++.h>
using namespace std;
int sum[][],ans[][];//sum 前i块中j出现的次数 ans 从i块到j块的答案
int n,m,c,a[],l,r,block,tot,t,vis[],bucket[],last;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if (ch=='-') f=-;ch=getchar();}
while(isdigit(ch)){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline int getpos(int x){return (x-)/block+;}
inline void build()
{
for (int i=;i<=tot;i++)
{
for (int j=;j<=c;j++) sum[i][j]=sum[i-][j];
for (int j=(i-)*block+;j<=i*block;j++) sum[i][a[j]]++;
}
for (int i=;i<=tot;i++)
for (int j=i;j<=tot;j++)
{
ans[i][j]=ans[i][j-];
for (int k=(j-)*block+;k<=j*block;k++)
{
if (!vis[a[k]]) vis[a[k]]=,bucket[a[k]]=;
else bucket[a[k]]++;
}
for (int k=(j-)*block+;k<=j*block;k++)
{
if (!vis[a[k]]) continue;
vis[a[k]]=;
int t=sum[j-][a[k]]-sum[i-][a[k]];
if (!t){if (bucket[a[k]]%==) ans[i][j]++;}
else{
if (t%==&&bucket[a[k]]%==) ans[i][j]++;
else if (t%==&&bucket[a[k]]%==) ans[i][j]--;
}
}
}
}
inline void query()
{
int cnt=;
if (getpos(r)-getpos(l)<=)
{
for (int i=l;i<=r;i++)
{
if (!vis[a[i]]) vis[a[i]]=,bucket[a[i]]=;
else bucket[a[i]]++;
}
for (int i=l;i<=r;i++)
{
if (!vis[a[i]]) continue;
vis[a[i]]=;
if (bucket[a[i]]%==) cnt++;
}
printf("%d\n",cnt);last=cnt;
return;
}
cnt=ans[getpos(l)+][getpos(r)-];
for (int i=l;i<=getpos(l)*block;i++)
{
if (!vis[a[i]]) vis[a[i]]=,bucket[a[i]]=;
else bucket[a[i]]++;
}
for (int i=(getpos(r)-)*block+;i<=r;i++)
{
if (!vis[a[i]]) vis[a[i]]=,bucket[a[i]]=;
else bucket[a[i]]++;
}
for (int i=l;i<=getpos(l)*block;i++)
{
if (!vis[a[i]]) continue;
vis[a[i]]=;
int t=sum[getpos(r)-][a[i]]-sum[getpos(l)][a[i]];
if (!t){if (bucket[a[i]]%==) cnt++;}
else{
if (t%==&&bucket[a[i]]%==) cnt++;
if (t%==&&bucket[a[i]]%==) cnt--;
}
}
for (int i=(getpos(r)-)*block+;i<=r;i++)
{
if (!vis[a[i]]) continue;
vis[a[i]]=;
int t=sum[getpos(r)-][a[i]]-sum[getpos(l)][a[i]];
if (!t){if (bucket[a[i]]%==) cnt++;}
else{
if (t%==&&bucket[a[i]]%==) cnt++;
if (t%==&&bucket[a[i]]%==) cnt--;
}
}
printf("%d\n",cnt);last=cnt;
}
int main()
{
n=read(),c=read(),m=read();
block=sqrt(n);
tot=n/block;
if (n%block) tot++;
for (int i=;i<=n;i++) a[i]=read();
build();
for (int i=;i<=m;i++)
{
l=read(),r=read();
l=(l+last)%n+,r=(r+last)%n+;
if (l>r) swap(l,r);
query();
}
return ;
}
【BZOJ2821】作诗 题解(分块+前缀和)的更多相关文章
- BZOJ2821 作诗(Poetize) 分块
题意 算法 经验总结 代码 题意 不带修改,查询数列[1,n]中[l,r]内的出现正偶数次的数的个数, 数列中的数 <= 1e5, n <= 1e5, 强制在线 算法 查询的内容: 区 ...
- BZOJ2821 作诗(分块)
和区间众数几乎一模一样的套路. // luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include&l ...
- BZOJ2821 作诗(Poetize) 【分块】
BZOJ2821 作诗(Poetize) Description 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI ...
- 【BZOJ2821】作诗(Poetize) 分块
Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次, ...
- 【分块】BZOJ2821 作诗(Poetize)
2821: 作诗(Poetize) Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 3265 Solved: 951[Submit][Status][ ...
- BZOJ2821:作诗——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2821 问题描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好 ...
- 作诗(si)[分块]
题目描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读 ...
- BZOJ 2821: 作诗(Poetize)( 分块 )
分块,分成N^0.5块.O(N^1.5)预处理出sm[i][j]表示前i块中j的出现次数, ans[i][j]表示第i~j块的答案. 然后就可以O(N^0.5)回答询问了.总复杂度O((N+Q)N^0 ...
- 洛谷 P4135 作诗 题解
题面. 之前做过一道很类似的题目 洛谷P4168蒲公英 ,然后看到这题很快就想到了解法,做完这题可以对比一下,真的很像. 题目要求区间内出现次数为正偶数的数字的数量. 数据范围1e5,可以分块. 我们 ...
随机推荐
- Jenkins - 解决集成 jmeter+ant 发送邮件时报错:java.lang.ClassNotFoundException: javax.mail.internet.MimeMessage
jenkins + jmeter +ant 发送邮件失败 问题原因 其实就是缺失 jar 包,导致某些类找不到了 解决方案 点击该网站,下载commons-email.jar包 点击该网站,下载act ...
- 使用IDEA创建Spring boot项目,继承mybaits。并进行简单的数据库查询操作
本文讲的是使用IEDA创建Spring boot项目,对于环境安装需要自行准备,如JDK1.8.Maven 3.3.IDEA编译器.Mysql5.7等需事前准备好. 1.创建Spring boot项目 ...
- Flask 基础组件(二):配置文件
配置参数 flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为: { 'DEBUG': get_debug_flag(default=False), 是否开启 ...
- 数据可视化之分析篇(四)PowerBI分析模型:产品关联度分析
https://zhuanlan.zhihu.com/p/64510355 逛超市的时候,面对货架上琳琅满目的商品,你会觉得这些商品的摆放,或者不同品类的货架分布是随机排列的吗,当然不是. 应该都听说 ...
- 数据可视化之PowerQuery篇(十三)Power BI总计行错误,这个技巧一定要掌握
https://zhuanlan.zhihu.com/p/102567707 前一段介绍过一个客户购买频次统计的案例: Power BI 数据分析应用:客户购买频次分布. 我并没有在文章中显示总计行 ...
- It's time for Django
本节内容 Django流程介绍 Django url Django view Django models Django template Django form Django admin Django ...
- Linux桌面进化史
自 20 世纪 90 年代初期以来,Linux 桌面也已从简单的窗口管理器发展为成熟.完整的桌面.那么它究竟是如何一步步发展至今的呢?作为从 1993 年就开始使用 Linux 的资深用户,FreeD ...
- python监控服务器应用日志,推送钉钉机器人,实时关注日志异常
生产环境多台服务器上部署了多个应用,日志出现报错时,无法及时反馈到开发人员.部署一个大型的运维监控应用,不但耗资源,而且配置也不简单. 简简单单写个python脚本来监控服务器日志就简单多了,废话不多 ...
- Dubbo的负载均衡算法源码分析
Dubbo提供了四种负载均衡:RandomLoadBalance,RoundRobinLoadBalance,LeastActiveLoadBalance,ConsistentHashLoadBala ...
- java 集合区别
TreeMap和TreeSet的区别 相同点: TreeMap和TreeSet都是有序的集合,也就是说他们存储的值都是排好序的. TreeMap和TreeSet都是非同步集合,因此他们不能在多线程之间 ...