zoukankan      html  css  js  c++  java
  • 晚间测试13 A. Dove 打扑克 vector +模拟

    题目描述


    分析

    这道题比较关键的一点就是要看出最终牌数的种类数不会超过 (sqrt{n})
    知道了这个性质我们就可以用 (vector) 维护一个有序的序列
    (vector) 中存放牌数的大小和有多少堆这样的牌
    每次二分插入和删除即可
    时间复杂度 (O(msqrt{n}))

    代码

    #include<cstdio>
    #include<vector>
    #define rg register
    inline int read(){
    	rg int x=0,fh=1;
    	rg char ch=getchar();
    	while(ch<'0' || ch>'9'){
    		if(ch=='-') fh=-1;
    		ch=getchar();
    	}
    	while(ch>='0' && ch<='9'){
    		x=(x<<1)+(x<<3)+(ch^48);
    		ch=getchar();
    	}
    	return x*fh;
    }
    const int maxn=1e6+5;
    int n,m,tp,siz[maxn],sum[maxn],fa[maxn],sta[maxn];
    int zhao(int xx){
    	if(xx==fa[xx]) return xx;
    	return fa[xx]=zhao(fa[xx]);
    }
    struct jie{
    	int val,cnt;
    	jie(){}
    	jie(int aa,int bb){
    		val=aa,cnt=bb;
    	}
    };
    std::vector<jie> g;
    int ef(int val){
    	rg int l=1,r=g.size(),mids;
    	while(l<=r){
    		mids=(l+r)>>1;
    		if(g[mids-1].val>=val) r=mids-1;
    		else l=mids+1;
    	}
    	return l-1;
    }
    int main(){
    	n=read(),m=read();
    	for(rg int i=1;i<=n;i++){
    		siz[i]=1;
    		fa[i]=i;
    	}
    	g.insert(g.begin(),jie(1,n));
    	rg int aa,bb,cc,dd,ee,ff;
    	rg long long ans=0;
    	for(rg int i=1;i<=m;i++){
    		aa=read();
    		if(aa==1){
    			bb=read(),cc=read();
    			dd=zhao(bb),ee=zhao(cc);
    			if(dd==ee) continue;
    			ff=ef(siz[dd]);
    			g[ff].cnt--;
    			if(g[ff].cnt==0) g.erase(g.begin()+ff);
    			ff=ef(siz[ee]);
    			g[ff].cnt--;
    			if(g[ff].cnt==0) g.erase(g.begin()+ff);
    			siz[dd]+=siz[ee];
    			siz[ee]=0;
    			if(g[g.size()-1].val<siz[dd]){
    				g.push_back(jie(siz[dd],1));
    			} else {
    				ff=ef(siz[dd]);
    				if(g[ff].val==siz[dd]) g[ff].cnt++;
    				else g.insert(g.begin()+ff,jie(siz[dd],1));
    			}
    			fa[ee]=dd;
    		} else {
    			bb=read();
    			ans=0;
    			tp=g.size();
    			for(rg int j=1;j<=tp;j++){
    				sum[j]=sum[j-1]+g[j-1].cnt;
    				sta[j]=g[j-1].val;
    			}
    			if(bb==0){
    				ans+=1LL*(sum[tp]-1)*sum[tp]/2LL;
    			} else {
    				ee=1,ff=1;
    				while(ee<=tp){
    					while(sta[ff]-sta[ee]<bb && ff<=tp) ff++;
    					if(sta[ff]-sta[ee]<bb || ff>tp) break;
    					ans+=1LL*(sum[ee]-sum[ee-1])*(sum[tp]-sum[ff-1]);
    					ee++;
    				}
    			}
    			printf("%lld
    ",ans);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    BZOJ1176: [Balkan2007]Mokia
    BZOJ1251: 序列终结者
    BZOJ1087: [SCOI2005]互不侵犯King
    Mike and gcd problem CodeForces
    Bank Hacking CodeForces
    Ilya And The Tree CodeForces
    欢迎使用CSDN-markdown编辑器
    Folding UVA
    Cake slicing UVA
    Headmaster's Headache UVA
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13894552.html
Copyright © 2011-2022 走看看