这题需要一个黑科技——摩尔投票。这是一个什么东西?一个神奇的方法求一个序列中出现次数大于长度一半的数。

简而言之就是同加异减

比如有一个代表投票结果的序列。

\[[1,2,1,1,2,1,1]
\]

我们记录一个\(num\)和\(cnt\)先别管它们是干什么的。我们模拟一遍模拟排序。

\[首先读第一个数1,num==0,我们把cnt+1=1,num=1
\]

\[第二个数2,num==1\neq2,我们把cnt-1=0,num不变
\]

\[然后第三个数1,num==0,我们把cnt+1=1,num=1
\]

\[第四个数1,num==1=1,cnt+1=2,num不变
\]

\[第五个数2,num==1\neq2,我们把cnt-1=1,num不变
\]

\[第六个数1,num==1=1,cnt+1=2,num不变
\]

最后的num就是出现次数大于一半的数。当然必须要保证真的有一个数出现次数大于一半。要不最后的num是错的。

摩尔投票有什么用呢,我们这道题有一个暴力的想法,对于每一个候选人建一颗平衡树,里面节点权值就是支持这个候选人的人的下标。 对于每一次询问,我们遍历每一个平衡树看看权值在\([l,r]\)中的节点有多少个,求max看看大不大于区间长度一半,就可以求出候选人了,维护也挺好维护。

但是每一次遍历平衡树太慢了,我们用摩尔投票先求出一个可能的答案,然后判断答案对应的那个平衡树就行了。然后摩尔投票有区间可加性可以用线段树维护。至此此题得到完美解决。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<ctime>
using namespace std;
const int N=501000;
int num[N*5],cnt[N*5];
int tot,rad[N],v[N],size[N],ch[N][2],root[N],x,y,z;
int n,m,a[N];
struct node{
int cnt,num;
};
void update(int now){
if(num[now*2]==num[now*2+1])num[now]=num[now*2],cnt[now]=cnt[now*2]+cnt[now*2+1];
else if(cnt[now*2]>cnt[now*2+1])num[now]=num[now*2],cnt[now]=cnt[now*2]-cnt[now*2+1];
else num[now]=num[now*2+1],cnt[now]=cnt[now*2+1]-cnt[now*2];
}
void build(int l,int r,int now){
if(l==r){
num[now]=a[l];
cnt[now]=1;
return;
}
int mid=(l+r)>>1;
build(l,mid,now*2);
build(mid+1,r,now*2+1);
update(now);
}
node check(int l,int r,int L,int R,int now){
if(l==L&&r==R){
node g;
g.num=num[now];
g.cnt=cnt[now];
return g;
}
int mid=(l+r)>>1;
if(L>mid)return check(mid+1,r,L,R,now*2+1);
else if(R<=mid)return check(l,mid,L,R,now*2);
else{
node a=check(l,mid,L,mid,now*2);
node b=check(mid+1,r,mid+1,R,now*2+1);
node g;
if(a.num==b.num)g.num=a.num,g.cnt=a.cnt+b.cnt;
else if(a.cnt>b.cnt)g.num=a.num,g.cnt=a.cnt-b.cnt;
else g.num=b.num,g.cnt=b.cnt-a.cnt;
return g;
}
}
void change(int l,int r,int x,int w,int now){
if(l==r){
num[now]=w;
return;
}
int mid=(l+r)>>1;
if(x>mid)change(mid+1,r,x,w,now*2+1);
else change(l,mid,x,w,now*2);
update(now);
}
int new_node(int x){
int now=++tot;
rad[now]=rand(),v[now]=x,size[now]=1;
return now;
}
void pushup(int x){
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(rad[x]>rad[y]){
ch[x][1]=merge(ch[x][1],y);
pushup(x);
return x;
}
else{
ch[y][0]=merge(x,ch[y][0]);
pushup(y);
return y;
}
}
void split(int &x,int &y,int now,int w){
if(now==0)x=y=0;
else{
if(v[now]<=w){
x=now;
split(ch[x][1],y,ch[x][1],w);
}
else{
y=now;
split(x,ch[y][0],ch[y][0],w);
}
pushup(now);
}
}
bool judge(int now,int l,int r){
split(x,z,root[now],r);
split(x,y,x,l-1);
int tmp=size[y];
root[now]=merge(merge(x,y),z);
if(tmp>(r-l+1)/2)return true;
else return false;
}
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int main(){
srand(time(NULL));
n=read();m=read();
for(int i=1;i<=n;i++){
a[i]=read();
root[a[i]]=merge(root[a[i]],new_node(i));
}
build(1,n,1);
while(m--){
int l=read(),r=read(),s=read(),k=read();
int f=check(1,n,l,r,1).num;
if(judge(f,l,r))s=f;
printf("%d\n",s);
for(int i=1;i<=k;i++){
f=read();
change(1,n,f,s,1);
split(x,z,root[a[f]],f);
split(x,y,x,f-1);
root[a[f]]=merge(x,z);
split(x,z,root[s],f);
root[s]=merge(merge(x,y),z);
a[f]=s;
}
}
int f=check(1,n,1,n,1).num;
if(judge(f,1,n))printf("%d",f);
else printf("-1");
return 0;
}

luogu P3765 总统选举(线段树维护摩尔投票+平衡树)的更多相关文章

  1. 【BZOJ4966】总统选举 线段树+随机化

    [BZOJ4966]总统选举 Description 黑恶势力的反攻计划被小C成功摧毁,黑恶势力只好投降.秋之国的人民解放了,举国欢庆.此时,原秋之国总统因没能守护好国土,申请辞职,并请秋之国人民的大 ...

  2. Luogu 3369 我用线段树骗了一道平衡树题……

    这篇博客毫无意义-- 只是表达一下我仍然会写树状数组和线段树-- 题目链接 #include <cstdio> #include <cstring> #include < ...

  3. 洛谷 P3765 总统选举 解题报告

    P3765 总统选举 题目背景 黑恶势力的反攻计划被小C成功摧毁,黑恶势力只好投降.秋之国的人民解放了,举国欢庆.此时,原秋之国总统因没能守护好国土,申请辞职,并请秋之国人民的大救星小C钦定下一任.作 ...

  4. 洛谷 P4198 楼房重建 线段树维护单调栈

    P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...

  5. 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

    肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个 ...

  6. Codeforces GYM 100114 D. Selection 线段树维护DP

    D. Selection Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descriptio ...

  7. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  8. [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

    题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...

  9. HDU3564 --- Another LIS (线段树维护最值问题)

    Another LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

随机推荐

  1. Run-time type information--RTTI

    In computer programming, run-time type information or run-time type identification (RTTI)[1] refers ...

  2. Unity 动画系统(Mecanim) 术语及翻译 表格

    原文 翻译 Animation Clip 视频片段 Avatar 阿凡达 Retargeting 重定向 Rigging 绑定 skinning 蒙皮 Animator Component 动画组件 ...

  3. JavaScript高级程序设计部分笔记

    1.JavaScript由三个不同的部分组成:ECMAScript(核心).DOM(文档对象模型).BOM(浏览器对象模型). 2.数据的引用类型 Object类型 Array类型 Data类型 Re ...

  4. python之类与对象属性的增删改查

    类属性与对象属性的增删改查 类属性的增删改查 class School: """ 文档 """ Teacher = "老王&quo ...

  5. 使用Git--将本地项目提交到Github

    前置工作 1. 在GitHub官网注册一个GitHub账号: 2. 安装git工具,在Git官网下载对应版本的Git: 方法一: 1. 进入Github首页,点击New repository新建一个项 ...

  6. 六、利用frp穿透连接内网的linx系统和windows系统

    服务端的配置 # frps.ini [common] bind_port = 7000 说明:防火墙放行该端口 启动:./frps -c ./frps.ini 后台启动:nohup ./frps -c ...

  7. CSS变量实用指南及注意事项

    近年来,一些动态特性已经开始成为 CSS 语言本身的一部分. CSS变量 – 官方的术语为 "自定义属性" – 已经已经加入规范并且具有很好的浏览器支持,而 CSS mixins ...

  8. HDU 4302 Contest 1

    维护两个优先队列即可.要注意,当出现蛋糕的位置刚好在狗的位置时,存在右边. 注意输出大小写... #include <iostream> #include <queue> #i ...

  9. EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER

    EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER ...

  10. 关于Servo项目中Rust代码行数的数据来源

    我两个月之前的一篇博客<为什么我说Rust是靠谱的编程语言>(下面简称原文),在当中"6. 两个半大型成功案例"一节.我以前写道: Servo: 下一代浏览器渲染引擎( ...