• Codeforces 1091E New Year and the Acquaintance Estimation Erdős–Gallai定理


     题目链接:E - New Year and the Acquaintance Estimation

    题解参考:

    Havel–Hakimi algorithm 和 Erdős–Gallai theorem

    按照后面那个定理说的,枚举$k∈[1,n]$,对于每一个$k$,计算出向等式两边加入$a_{n+1}$的合法范围,最后所有范围求交即可

    最后按照前面那个定理说的,枚举最终区间的时候,对于合法真正的$a_{n+1}$进行输出即可

    比赛的时候没看见后面那个定理,推了半天

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

    正常人写法:

    #include <bits/stdc++.h>
    #define ll long long
    #define rep(ii,a,b) for(ll ii=a;ii<=b;++ii)
    using namespace std;
    int n;
    int main() {
    	ios::sync_with_stdio(false);cin.tie(0);
    	cin>>n;
    	vector<ll>deg(n),sum(n+1);
    	for(auto&i:deg) cin>>i;
    	sort(deg.begin(),deg.end());
    	rep(i,0,n-1) sum[i+1]=sum[i]+deg[i];
    	int pos=0;
    	ll lower=-1,upper=n+2;
    	rep(k,1,n){
        while(pos<n&&deg[pos]<k) pos++;
        ll uper=min(n-k,(ll)pos);
        ll eql=sum[n]-sum[n-k];
    		ll eqr=k*(k-1)+sum[uper]+k*(n-k-uper);
    		ll amin=eql-eqr;
    		ll amax=eqr-eql+deg[n-k]+min(deg[n-k],(ll)k);
    		lower=max(amin,lower);
    		upper=min(amax,upper);
    	}
    	if(upper-lower<0) cout<<-1;
    	else rep(i,lower,upper) if((sum[n]+i)%2==0) cout<<i<<' ';
    }
    

      

     弱智写法:

    #include <bits/stdc++.h>
    #define ll long long
    #define rep(ii,a,b) for(ll ii=a;ii<=b;++ii)
    using namespace std;
    int n;
    class segtree{
    #define nd  node[now]
    #define ndl node[now<<1]
    #define ndr node[now<<1|1]
    	public:
    	struct segnode {
    		int l,r,mx,tag;
    		int mid(){return (r+l)>>1;}
    		int len(){return r-l+1;}
    		void update(int x){mx+=x,tag+=x;}
    	};
    	vector<segnode> node;
    	segtree(int n) {node.resize(n<<2|3);maketree(1,n);}
    	void pushup(int now){nd.mx=max(ndl.mx,ndr.mx);}
    	void pushdown(int now){
    		if(nd.tag){
    			ndl.update(nd.tag);
    			ndr.update(nd.tag);
    			nd.tag=0;
    		}
    	}
    	void maketree(int s,int t,int now=1){
    		nd={s,t,0,0};
    		if(s==t)return ;
    		maketree(s,(s+t)>>1,now<<1); maketree(((s+t)>>1)+1,t,now<<1|1);
    	}
    	void update(int s,int t,int x,int now=1){
    		if(s>nd.r||t<nd.l) return ;
    		if(s<=nd.l&&t>=nd.r){
    			nd.update(x);
    			return ;
    		}
    		pushdown(now);
    		update(s,t,x,now<<1); update(s,t,x,now<<1|1);
    		pushup(now);
    	}
    	int query_lowerbound(int now=1){
    		if(nd.mx<n) return -1;
    		if(nd.len()==1) return nd.l;
    		pushdown(now);
    		if(ndl.mx>=n) return query_lowerbound(now<<1);
    		else return query_lowerbound(now<<1|1);
    	}
    	int query_upperbound(int now=1){
    		if(nd.mx<n) return -1;
    		if(nd.len()==1) return nd.l;
    		pushdown(now);
    		if(ndr.mx>=n)return query_upperbound(now<<1|1);
    		else return query_upperbound(now<<1);
    	}
    #undef nd
    #undef ndl
    #undef ndr
    };
    int main() {
    	ios::sync_with_stdio(false);cin.tie(0);
    	cin>>n;
    	segtree tree(n);
    	vector<ll>deg(n),sum(n+1);
    	for(auto&i:deg) cin>>i;
    	sort(deg.begin(),deg.end());
    	rep(i,0,n-1) sum[i+1]=sum[i]+deg[i];
    	int pos=0;
    	rep(k,1,n){
        while(pos<n&&deg[pos]<k) pos++;
        ll uper=min(n-k,(ll)pos);
        ll eql=sum[n]-sum[n-k];
    		ll eqr=k*(k-1)+sum[uper]+k*(n-k-uper);
    		ll amin=eql-eqr;
    		ll amax=eqr-eql+deg[n-k]+min(deg[n-k],(ll)k);
    		if(amin<=min(k,deg[n-k])) tree.update(max(amin,0ll),deg[n-k],1);
    		if(amax>deg[n-k]) tree.update(deg[n-k]+1,min(amax,(ll)n),1);
    	}
    	int lower=tree.query_lowerbound(),upper=tree.query_upperbound();
    	if(lower==-1) cout<<-1;
    	else rep(i,lower,upper)if((sum[n]+i)%2==0) cout<<i<<' ';
    }
    

      

  • 相关阅读:
    如何让百度网盘下载速度达60MB/s!
    记一次内存溢出问题的排查、分析过程及解决思路
    使用maven命令打包可执行jar方法
    java实现四则运算
    POI如何合并单元格
    我是如何从功能测试成功转型自动化测试人员的?
    Edgar:Netflix分布式系统的可视化问题诊断平台实践
    Uber的API生命周期管理平台边缘网关(Edge Gateway)的设计实践
    UBer面向领域的微服务体系架构实践
    技术团队:问题被过度的夸大小题大做,你该怎么办?
  • 原文地址:https://www.cnblogs.com/nervendnig/p/10222501.html
Copyright © 2020-2023  润新知