zoukankan      html  css  js  c++  java
  • 【BZOJ4966】总统选举 线段树+随机化

    【BZOJ4966】总统选举

    Description

    黑恶势力的反攻计划被小C成功摧毁,黑恶势力只好投降。秋之国的人民解放了,举国欢庆。此时,原秋之国总统因没能守护好国土,申请辞职,并请秋之国人民的大救星小C钦定下一任。作为一名民主人士,小C决定举行全民大选来决定下一任。为了使最后成为总统的人得到绝大多数人认同,小C认为,一个人必须获得超过全部人总数的一半的票数才能成为总统。如果不存在符合条件的候选人,小C只好自己来当临时大总统。为了尽可能避免这种情况,小C决定先进行几次小规模预选,根据预选的情况,选民可以重新决定自己选票的去向。由于秋之国人数较多,统计投票结果和选票变更也成为了麻烦的事情,小C找到了你,让你帮他解决这个问题。
     
    【问题描述】
    秋之国共有n个人,分别编号为1,2,…,n,一开始每个人都投了一票,范围1~n,表示支持对应编号的人当总统。共有m次预选,每次选取编号[li,ri]内的选民展开小规模预选,在该区间内获得超过区间大小一半的票的人获胜,如果没有人获胜,则由小C钦定一位候选者获得此次预选的胜利(获胜者可以不在该区间内),每次预选的结果需要公布出来,并且每次会有ki个人决定将票改投向该次预选的获胜者。全部预选结束后,公布最后成为总统的候选人 

    Input

    第一行两个整数n,m,表示秋之国人数和预选次数。
    第二行n个整数,分别表示编号1~n的选民投的票。
    接下来m行,每行先有4个整数,分别表示li,ri,si,ki,si表示若此次预选无人胜选,视作编号为si的人获得胜利
    接下来ki个整数,分别表示决定改投的选民。
    1<=n,m<=500,000,Σki<=1,000,000,1<=li<=ri<=n,1<=si<=n。

    Output

    共m+1行,前m行表示各次预选的结果,最后一行表示最后成为总统的候选人,若最后仍无人胜选,输出-1。

    Sample Input

    5 4
    1 2 3 4 5
    1 2 1 1 3
    5 5 1 2 2 4
    2 4 2 0
    3 4 2 1 4

    Sample Output

    1
    5
    5
    2
    -1

    题解:正解见Claris的博客

    然而本人还是用随机化过的,并且由于姿势太弱,在时间上略有点卡。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    int n,m,tot;
    const int maxn=500010;
    const int tim=15;
    int rt[maxn],v[maxn];
    struct node
    {
    	int siz,ls,rs;
    }s[maxn*60];
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void insert(int &x,int l,int r,int y,int v)
    {
    	if(!x)	x=++tot;
    	s[x].siz+=v;
    	if(l==r)	return ;
    	int mid=l+r>>1;
    	if(y<=mid)	insert(s[x].ls,l,mid,y,v);
    	else	insert(s[x].rs,mid+1,r,y,v);
    }
    int query(int x,int l,int r,int a,int b)
    {
    	if(!x)	return 0;
    	if(a<=l&&r<=b)	return s[x].siz;
    	int mid=l+r>>1;
    	if(b<=mid)	return query(s[x].ls,l,mid,a,b);
    	if(a>mid)	return query(s[x].rs,mid+1,r,a,b);
    	return query(s[x].ls,l,mid,a,b)+query(s[x].rs,mid+1,r,a,b);
    }
    int main()
    {
    	srand(2333666);
    	n=rd(),m=rd();
    	int i,j,a,b,c,d;
    	for(i=1;i<=n;i++)	v[i]=rd(),insert(rt[v[i]],1,n,i,1);
    	for(i=1;i<=m;i++)
    	{
    		a=rd(),b=rd();
    		for(j=1;j<=tim;j++)
    		{
    			c=v[rand()%(b-a+1)+a];
    			if(query(rt[c],1,n,a,b)>(b-a+1)/2)	break;
    		}
    		if(j<=tim)	rd();
    		else	c=rd();
    		printf("%d
    ",c);
    		d=rd();
    		for(j=1;j<=d;j++)	a=rd(),insert(rt[v[a]],1,n,a,-1),v[a]=c,insert(rt[c],1,n,a,1);
    	}
    	for(i=1;i<=n;i++)	if(s[rt[i]].siz>n/2)
    	{
    		printf("%d
    ",i);
    		return 0;
    	}
    	printf("-1");
    	return 0;
    }//5 4 1 2 3 4 5 1 2 1 1 3 5 5 1 2 2 4 2 4 2 0 3 4 2 1 4
  • 相关阅读:
    FZU 2112 并查集、欧拉通路
    HDU 5686 斐波那契数列、Java求大数
    Codeforces 675C Money Transfers 思维题
    HDU 5687 字典树插入查找删除
    HDU 1532 最大流模板题
    HDU 5384 字典树、AC自动机
    山科第三届校赛总结
    HDU 2222 AC自动机模板题
    HDU 3911 线段树区间合并、异或取反操作
    CodeForces 615B Longtail Hedgehog
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7412218.html
Copyright © 2011-2022 走看看