题意:

N个数,M组询问,每次问[l,r]中有多少个数出现正偶数次。

思路:

把N个数分成sqrt(n)块,预处理d[i][j]表示第i块起点到第j块末尾的答案

枚举起点i,并维护一个数组记录每个数到目前为止出现的次数,从偶变奇、从奇变偶时相应增减答案。

把每个数在数列中出现的位置从小到大排序后放入到一个数组Arr中备用。

读入每个询问[l,r]。如果l和r在同一个块中暴力即可,否则设l所在块的末尾为l’,r所在块的起点为r’,[l’+1,r’-1]的答案已经预处理出。扫描l~l’, r’~r的所有数,统计每个数出现的次数cnt,第一次出现时把它加入队列。

对于队列中的每个数,在数组Arr中二分l’+1和r’-1,得到在[l’+1,r’-1]中出现的次数k。通过对k和当前队列中的数的cnt进行奇偶性讨论更新答案

(from lyd的题解…)

我们就可以vector +lower_bound()

搞定~

(也可以用可持久化线段树之类的东西…)

最后  祝他们幸福……

//By SiriusRen
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100005;
int n,c,m,a[N],Block,block[N],f[1111][1111],vis[N],ans,l,r,stk[N],top;
vector<int>vec[N];
int main(){
scanf("%d%d%d",&n,&c,&m),Block=sqrt(n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),block[i]=(i-1)/Block+1,vec[a[i]].push_back(i);
for(int i=1;i<=block[n];i++){
memset(vis,0,sizeof(vis));int temp=0;
for(int j=lower_bound(block,block+1+n,i)-block;j<=n;j++){
vis[a[j]]++;
if(vis[a[j]]%2==0)temp++;
else if(vis[a[j]]!=1)temp--;
if(block[j]!=block[j+1])f[i][block[j]]=temp;
}
}
memset(vis,0,sizeof(vis));
for(int i=1;i<=m;i++){
scanf("%d%d",&l,&r);
l=(l+ans)%n+1,r=(r+ans)%n+1;
if(l>r)swap(l,r);ans=0;
int L=block[l]+1,R=block[r];
if(L<R){
int ll=lower_bound(block+1,block+1+n,L)-block-1;
int rr=lower_bound(block+1,block+1+n,R)-block;
R--;top=0;
for(int i=l;i<=ll;i++)vis[a[i]]++,stk[++top]=a[i];
for(int i=rr;i<=r;i++)vis[a[i]]++,stk[++top]=a[i];
ans=f[L][R];
for(int i=1;i<=top;i++)if(vis[stk[i]]){
int t=lower_bound(vec[stk[i]].begin(),vec[stk[i]].end(),rr)-
lower_bound(vec[stk[i]].begin(),vec[stk[i]].end(),ll+1);
if(!t){if(vis[stk[i]]%2==0)ans++;}
else if(t%2==0){if(vis[stk[i]]%2==1)ans--;}
else if(t%2==1&&vis[stk[i]]%2==1)ans++;
vis[stk[i]]=0;
}
}
else{
top=0;
for(int i=l;i<=r;i++)vis[a[i]]++;
for(int i=l;i<=r;i++)if(vis[a[i]]){
if(vis[a[i]]%2==0)ans++;
vis[a[i]]=0;
}
}
printf("%d\n",ans);
}
}

BZOJ 2821 分块+二分的更多相关文章

  1. bzoj 2821 分块处理

    大题思路就是分块,将n个数分成sqrt(n)个块,然后 处理出一个w数组,w[i,j]代表第i个块到第j个块的答案 那么对于每组询问l,r如果l,r在同一个块中,直接暴力做就行了 如果不在同一个块中, ...

  2. bzoj 2821 分块

    分块: 先预处理,将原序列分成长度为len的许多块,计算从第i块到第j块的答案,(可以做到O(n*n/len)). 每次询问时,将询问的区间分成三部分,:左边,中间,右边,中间是尽量大的一个块区间,其 ...

  3. [BZOJ 2821] 作诗(Poetize) 【分块】

    题目链接:BZOJ - 2821 题目分析 因为强制在线了,所以无法用莫队..可以使用分块来做. 做法是,将 n 个数分成 n/x 个块,每个块大小为 x .先预处理出 f[i][j] ,表示从第 i ...

  4. BZOJ 3343: 教主的魔法(分块+二分查找)

    BZOJ 3343: 教主的魔法(分块+二分查找) 3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved:  ...

  5. Bzoj 3343: 教主的魔法(分块+二分答案)

    3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MB Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息 ...

  6. [BZOJ 2821] 作诗

    Link: BZOJ 2821 传送门 Solution: 一道类似区间众数的经典分块 由于个数为偶数这样的条件不能支持快速合并 因此要先$O(n*sqrt(n))$预处理出$pre[i][j]$表示 ...

  7. BZOJ_3343_教主的魔法_分块+二分查找

    BZOJ_3343_教主的魔法_分块+二分查找 题意:教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列被编号为 ...

  8. 【bzoj2957】楼房重建 分块+二分查找

    题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子.为了简化问题,我们考虑这些事件发生在一个二 ...

  9. 【bzoj2453】维护队列/【bzoj2120】数颜色 分块+二分

    题目描述 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好, ...

随机推荐

  1. less常用方法

    最近在开发中使用了less,总结一下less一些常用的方法: 1.可以定义变量 SASS允许使用变量,所有变量以$开头. $blue : #1875e7; div { color : $blue; } ...

  2. Android 微信分享与QQ分享功能

    微信分享与QQ分享功能现在都挺常见的,可以根据一些第三方社会化分功能快速实现,不过多多少少都不怎么纯净,最好都是自己看官方文档来实现就最好了~ 一.微信分享 微信分享功能需要先在微信开放平台注册应用并 ...

  3. Linux学习笔记(Redhat)

    一.开始 linux平台上的开发 vi.gcc.gdb.make.jdk.tomcat.mysql. linux基本操作 c语言功底<c专家编程>和java语言 学习unix高级编程 &l ...

  4. spring过滤器篇

    CharacterEncodingFilter spring的web包下的一个过滤器,用于设置程序的字符编码,它有两个参数encoding和forceEncoding. encoding:字符集,将过 ...

  5. Python基础:dict & set

    一 :dict 1:Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度. eg: dict查找 ...

  6. Tjoi2019 甲苯先生和大中锋的字符串 后缀自动机_差分

    tjoi胆子好大,直接出了两道送分题...... 都 9102 年了,还有省选出模板题QAQ...... Code: #include <bits/stdc++.h> #define se ...

  7. linu问题集锦

    问题1 系统卡 慢 执行命令延迟/var/spool/mail下root文件过大导致/var磁盘空间92% cd / && du | sort -n | tail -n 10 查看排名 ...

  8. Project Euler 14 Longest Collatz sequence

    题意:对于任意一个数 N ,寻找在 100,0000 之内按照规则( N 为奇数 N = N * 3 + 1 ,N 为偶数 N = N / 2 ,直到 N = 1 时的步数 )步数的最大值 思路:记忆 ...

  9. gud-cloud

    架构:计算层:三台机器,包含处理器,内存条,外加一个64GB的存储器,这个存储器安装exsi主机,然后创建cvm虚拟机,硬盘空间选择在之前安装exsi主机的存储器里面 存储层:三台机器内置多个硬盘8T ...

  10. PHP实现并发请求

    后端服务开发中经常会有并发请求的需求,比如你需要获取10家供应商的带宽数据(每个都提供不同的url),然后返回一个整合后的数据,你会怎么做呢? 在PHP中,最直观的做法foreach遍历urls,并保 ...