BZOJ2724 蒲公英 【分块】
BZOJ2724 蒲公英
题目背景
亲爱的哥哥: 
你在那个城市里面过得好吗? 
我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的…… 
最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢! 
哥哥你要快点回来哦! 
爱你的妹妹 Violet 
Azure 读完这封信之后微笑了一下。 
“蒲公英吗……”
题目描述
在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。 
为了简化起见,我们把所有的蒲公英看成一个长度为n的序列 (a1,a2..an)" role="presentation">(a1,a2..an)(a1,a2..an)其中 ai" role="presentation">aiai为一个正整数,表示第i棵蒲公英的种类编号。 
而每次询问一个区间 [l,r],你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。 
注意,你的算法必须是在线的
输入输出格式
输入格式:
第一行两个整数 n,m ,表示有n株蒲公英,m 次询问。 
接下来一行n个空格分隔的整数 ai" role="presentation">aiai ,表示蒲公英的种类 
再接下来m 行每行两个整数 l0,r0" role="presentation">l0,r0l0,r0 ,我们令上次询问的结果为 x(如果这是第一次询问, 则 x=0)。 
令l=(l0+x−1)modn+1,r=(r0+x−1)modn+1" role="presentation">l=(l0+x−1)modn+1,r=(r0+x−1)modn+1l=(l0+x−1)modn+1,r=(r0+x−1)modn+1 ,如果 l>r,则交换 l,r 。 
最终的询问区间为[l,r]。
输出格式:
输出m 行。每行一个整数,表示每次询问的结果。
输入输出样例
输入样例#1
6 3  
1 2 3 2 1 2  
1 5  
3 6  
1 5
输出样例#1:
1  
2  
1 
说明 
对于 20% 的数据,保证 1≤n,m≤30001≤n,m≤3000" role="presentation">1≤n,m≤30001≤n,m≤30001≤n,m≤30001≤n,m≤3000。 
对于 100% 的数据,保证 1≤n≤40000,1≤m≤50000,1≤ai≤109" role="presentation">1≤n≤40000,1≤m≤50000,1≤ai≤1091≤n≤40000,1≤m≤50000,1≤ai≤109
区间求众数
分块
cnt[i][j]" role="presentation">cnt[i][j]cnt[i][j]表示第i个数在前j个块中的数量 
ans[i][j]" role="presentation">ans[i][j]ans[i][j]表示第i到第j个块中的众数 
先离散,然后预处理cnt" role="presentation">cntcnt和ans" role="presentation">ansans,对于查询,先把答案设定为完整块的众数,不是完整块的部分就暴力枚举进行比较好了
时间&空间效率O(nsqrt(n))" role="presentation">O(nsqrt(n))O(nsqrt(n))
#include<bits/stdc++.h>
using namespace std;
#define N 210
#define M 40010
#define For(x,a,b) for(int x=a;x<=b;x++)
map<int,int> mp;
int n,m,tot=0,lastans=0;
int a[M],b[M],pre[M],t[N]={0};
int block[M],L[N],R[N];
int cnt[M][N]={0},ans[N][N]={0};
int calc(int id,int lb,int rb){
    return cnt[id][rb]-cnt[id][lb-1];
}
void init(){
    int siz=sqrt(n);
    For(i,1,n)block[i]=(i-1)/siz+1;
    int bsiz=block[n];
    For(i,1,bsiz)L[i]=R[i-1]+1,R[i]=min(n,i*siz);
    For(i,1,n)cnt[b[i]][block[i]]++;
    For(i,1,tot)For(j,1,bsiz)cnt[i][j]+=cnt[i][j-1];
    For(i,1,bsiz)
        For(j,i,bsiz){
            int tmp=ans[i][j-1];
            For(k,L[j],R[j]){
                int t1=calc(b[k],i,j),t2=calc(tmp,i,j);
                if((t1==t2&&pre[b[k]]<pre[tmp])||t1>t2)tmp=b[k];
            }
            ans[i][j]=tmp;
        }
}
bool check(int id,int tmp){
    if(t[id]>t[tmp])return 1;
    if(t[id]==t[tmp]&&pre[id]<pre[tmp])return 1;
    return 0;
}
int solve(int l,int r){
    int pl=block[n]+1,pr=0;
    For(i,1,block[n])if(L[i]>=l)pl=min(pl,i);
    For(i,1,block[n])if(R[i]<=r)pr=max(pr,i);
    if(pl>pr){
        int tmp=0;
        For(i,l,r)t[b[i]]=0;
        For(i,l,r)t[b[i]]++;
        For(i,l,r)if(check(b[i],tmp))tmp=b[i];
        return tmp;
    }
    int tmp=ans[pl][pr];
    t[tmp]=calc(tmp,pl,pr);
    For(i,l,L[pl]-1)t[b[i]]=calc(b[i],pl,pr);
    For(i,R[pr]+1,r)t[b[i]]=calc(b[i],pl,pr);
    For(i,l,L[pl]-1)t[b[i]]++;
    For(i,R[pr]+1,r)t[b[i]]++;
    For(i,l,L[pl]-1)if(check(b[i],tmp))tmp=b[i];
    For(i,R[pr]+1,r)if(check(b[i],tmp))tmp=b[i];
    return tmp;
}
int main(){
    scanf("%d%d",&n,&m);
    For(i,1,n){
        scanf("%d",&a[i]);
        if(!mp.count(a[i])){
            mp[a[i]]=++tot;
            pre[tot]=a[i];
        }
        b[i]=mp[a[i]];
    }
    init();
    For(i,1,m){
        int l,r;scanf("%d%d",&l,&r);
        l=(l+lastans-1)%n+1;
        r=(r+lastans-1)%n+1;
        if(l>r)swap(l,r);
        lastans=pre[solve(l,r)];
        printf("%d\n",lastans);
    }
    return 0;
}BZOJ2724 蒲公英 【分块】的更多相关文章
- [日常摸鱼]bzoj2724蒲公英-分块
		区间众数经典题~ http://begin.lydsy.com/JudgeOnline/problem.php?id=4839这里可以提交~ 题意大概就是没有修改的询问区间众数,如果有一样的输出最小的 ... 
- 【BZOJ2724】[Violet 6]蒲公英 分块+二分
		[BZOJ2724][Violet 6]蒲公英 Description Input 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n ... 
- BZOJ2724 [Violet 6]蒲公英 分块
		原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2724.html 题目传送门 - BZOJ2724 题意 求区间最小众数,强制在线. $n$ 个数,$m ... 
- 【bzoj2724】[Violet 6]蒲公英  分块+STL-vector
		题目描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 样例输入 6 3 1 2 3 2 1 2 1 5 3 ... 
- BZOJ2724 [Violet]蒲公英   分块
		题目描述 经典区间众数题目 然而是权限题,所以题目链接放Luogu的 题解 因为太菜所以只会$O(n*\sqrt{n}+n*\sqrt{n}*log(n))$的做法 就是那种要用二分的,并不会clj那 ... 
- bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式
		这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ... 
- BZOJ 2724: [Violet 6]蒲公英( 分块 )
		虽然AC了但是时间惨不忍睹...不科学....怎么会那么慢呢... 无修改的区间众数..分块, 预处理出Mode[i][j]表示第i块到第j块的众数, sum[i][j]表示前i块j出现次数(前缀和, ... 
- [Violet]蒲公英   分块
		发现写算法专题老是写不动,,,, 所以就先把我在luogu上的题解搬过来吧! 题目大意:查询区间众数,无修改,强制在线 乍一看是一道恐怖的题,仔细一看发现并没有那么难: 大致思路是这样的,首先我们要充 ... 
- [BZOJ2724] 蒲公英
		题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了.我觉得把那么可怕 ... 
随机推荐
- BZOJ4787/UOJ290 【ZJOI2017】仙人掌
			本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ... 
- WebAPI项目  IHttpActionResult不识别解决办法
			转自:http://blog.csdn.net/nnnnnbody/article/details/16945253 使用ASP.NET Web API构造基于restful风格web service ... 
- 分布式缓存集群方案特性使用场景(Memcache/Redis(Twemproxy/Codis/Redis-cluster))优缺点对比及选型
			分布式缓存集群方案特性使用场景(Memcache/Redis(Twemproxy/Codis/Redis-cluster))优缺点对比及选型 分布式缓存特性: 1) 高性能:当传统数据库面临大规模 ... 
- 【转】VIM 中设置Tab
			灵活操作 Vim 中的 Tabsgaleki post @ 2007年11月16日 05:07PM in Vim Tips with tags: vim tabs Vim 支持 Tabs,也就是标签页 ... 
- jmeter-02 JMeter 生成HTML性能报告
			Report Dashboard: JMeter3.0 后提供的扩展模块,支持从测试计划中获取图形和统计数据,生成HTML页面格式图形化报告. 快速入门演示 一.准备测试计划 mock_api .jm ... 
- 第四章 SSL和Proxy高级选项
			在前一章,我们已经学习了HTTP消息如何通过Burp Proxy进行拦截和处理,本章我们将继续学习HTTPS协议消息的拦截和处理. HTTPS协议是为了数据传输安全的需要,在HTTP原有的基础上,加入 ... 
- UVA-11090 Going in Cycle!! (平均值最大回路)
			题目大意:一个n个点,m条无向边的图,求出平均权值最小的回路. 题目分析:二分枚举平均值mid,只需判断是否存在平均值小于mid的回路,即判断是否有sum(wi)<mid*k (1≤i≤k),只 ... 
- 上下行分流下行负载方式和能ping通但不能打开
			1 下行线路负载方式选择 目的端口+协议 否则有可能出现微信443端口图片打不开的情况. 2.彭ping通但是打不开的情况下将上行线路mtu值改小 由1500改为1450 
- 由浅入深了解EventBus:(四)
			事件注册 在EventBus3.0框架中订阅者对事件进行注册/订阅是通过EventBus类中的register方法来实现的,register的方法参数就是我们的订阅者的实例; public void ... 
- CF Round #456 (Div. 2)
			这时我第一次打CF 然后一看t1 哇好水 然后秒A了 看B 哇好像也很水 然后A了 看了C 不会... 然后去看D 似乎概率 然后推了一下,退出来了 然后看E 不会... 接着问了半个小时怎么hack ... 
