前言:世间还有这么卡常的题……

------------------

题目链接

题目大意:给定长度为$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】作诗 题解(分块+前缀和)的更多相关文章

  1. BZOJ2821 作诗(Poetize) 分块

    题意 算法 经验总结 代码 题意 不带修改,查询数列[1,n]中[l,r]内的出现正偶数次的数的个数, 数列中的数 <= 1e5, n <= 1e5, 强制在线 算法 ​ 查询的内容: 区 ...

  2. BZOJ2821 作诗(分块)

    和区间众数几乎一模一样的套路. // luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include&l ...

  3. BZOJ2821 作诗(Poetize) 【分块】

    BZOJ2821 作诗(Poetize) Description 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI ...

  4. 【BZOJ2821】作诗(Poetize) 分块

    Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次, ...

  5. 【分块】BZOJ2821 作诗(Poetize)

    2821: 作诗(Poetize) Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 3265  Solved: 951[Submit][Status][ ...

  6. BZOJ2821:作诗——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2821 问题描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好 ...

  7. 作诗(si)[分块]

    题目描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读 ...

  8. 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 ...

  9. 洛谷 P4135 作诗 题解

    题面. 之前做过一道很类似的题目 洛谷P4168蒲公英 ,然后看到这题很快就想到了解法,做完这题可以对比一下,真的很像. 题目要求区间内出现次数为正偶数的数字的数量. 数据范围1e5,可以分块. 我们 ...

随机推荐

  1. Java入门系列之final

    前言 在C#经典面试中掺杂过Java的final关键字,主要用于类不能被继承,在C#则是利用关键字seal修饰类为密封类,而在Java中的final关键字的具体用法包含C#中const.readonl ...

  2. shell专题(二):Shell解析器

    (1)Linux提供的Shell解析器有: [atguigu@hadoop101 ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin /bin/da ...

  3. SQLAlchemy03 /外键、连表关系

    SQLAlchemy03 /外键.连表关系 目录 SQLAlchemy03 /外键.连表关系 1.外键 2.ORM关系以及一对多 3.一对一的关系 4.多对多的关系 5.ORM层面的删除数据 6.OR ...

  4. POJ 1063 Flip and Shift 最详细的解题报告

    题目来源:Flip and Shift 题目大意:一个椭圆形的环形容器中有黑色和白色两种盘子,问你是否可以将黑色的盘子连续的放在一起.你可以有以下两种操作: 1.顺时针旋转所有的盘子 2.顺时针旋转3 ...

  5. bzoj3196Tyvj1730二逼平衡树

    bzoj3196Tyvj1730二逼平衡树 题意: 维护一个数列,操作:查询k在区间内的排名.查询区间内排名为k的值3.修改某一位上的数值.查询k在区间内的前驱(前驱定义为小于x,且最大的数).查询k ...

  6. Linux 通过源代码安装和编译程序

    Linux源代码安装在平常工作学习中经常用到,总结下步骤↓↓↓ 第一步:#mount /dev/cdrom/mnt (挂载一个软盘) 第二步:手动安装httpd-2.4.25.tar.gz 依赖关系包 ...

  7. 【高性能Mysql 】读书笔记(一)

    第1章 Mysql架构与历史 MYSQL最重要.最与众不同的特性是它的存储引擎架构,这种架构的设计将查询处理( Query Processing)及其他系统任务( Server Task)和数据的存储 ...

  8. Python Ethical Hacking - NETWORK_SCANNER(2)

    DICTIONARIES Similar to lists but use key instead of an index. LISTS List of values/elements, all ca ...

  9. Python Ethical Hacking - Persistence(1)

    PRESISTENCE Persistence programs start when the system starts. Backdoors -> maintain our access. ...

  10. T2 监考老师 题解

    第二题,他并不是多难的算法.甚至连搜索都不用,他的题目要求和数据断定了他第二题的地位. 在一个大试场里,有 n 行 m 列的考生,小王和众多同学正在考试,这时,有一部分考生 作弊,当然,监考老师能发现 ...