【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,可以分块. 我们 ...
随机推荐
- 使用eval将字符串转化成字典时报name 'null' is not defined错误解决办法
在接口测试过程中,为了取值将形如字典形式的字符串使用eval()方法转化成字典方便取值 str={"code":100,"num":1,"data&q ...
- 数据分析04 /基于pandas的DateFrame进行股票分析、双均线策略制定
数据分析04 /基于pandas的DateFrame进行股票分析.双均线策略制定 目录 数据分析04 /基于pandas的DateFrame进行股票分析.双均线策略制定 需求1:对茅台股票分析 需求2 ...
- Flask 基础组件(六):Session
除请求对象之外,还有一个 session 对象.它允许你在不同请求间存储特定用户的信息.它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥. 设 ...
- Iphone上对于动态生成的html元素绑定点击事件$(document).click()失效解决办法
在Iphone上,新生成的DOM元素不支持$(document).click的绑定方法,该怎么办呢? 百度了N久都没找到解决办法,在快要走投无路之时,试了试Google,我去,还真找到了,歪国人就是牛 ...
- 什么是A站、B站、C站、D站、E站、F站、G站、HIJKLM站N站?
A站AcFun弹幕视频网,简称“A站”,成立于2007年6月,取意于Anime Comic Fun,是中国大陆第一家弹幕视频网站.A站以视频为载体,逐步发展出基于原生内容二次创作的完整生态,拥有高质量 ...
- C#数据结构与算法系列(二十二):快速排序算法(QuickSort)
1.介绍 快速排序(QuickSort)是对冒泡排序的一种改进,基本思想是:通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数 ...
- centos7中防火墙转为iptables
1.关闭firewall systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止fir ...
- python 结合redis 队列 做一个例子
结合redis 队列 做了一个例子 #!/usr/bin/env python # coding: utf-8 # @Time : 2018/12/21 0021 13:57 # @Site : # ...
- Java7/8 中的 HashMap 和 ConcurrentHashMap
Java7 HashMap 数组+链表 Java7 ConcurrentHashMap Segment数组+HashEntry数组链表+ReenTrantLock分段锁 Java8 HashMa ...
- Dcoker docker: Error starting userland proxy: Bind for 0.0.0.0:80: unexpected error (Failure EADDRINUSE).
https://stackoverflow.com/questions/46533482/error-starting-userland-proxy-bind-for-0-0-0-080-unexpe ...