zoukankan      html  css  js  c++  java
  • P4971 断罪者

    传送门

    首先,不难看出可以给每个集合开一个可并堆,然后乱搞就可以了

    主要的问题就是将罪恶值清零和减少罪恶值该怎么搞

    罪恶值清零可以直接找到这个节点然后把值变为零,再把它的左右儿子分别并到这个节点所在的根节点的可并堆里

    减少罪恶值可以直接把根节点减去这个值,然后把左右儿子重新合并上去就好了

    明明完全不会指针却为了卡常白花了一个小时最后只好妥协用结构体

    //minamoto
    #include<bits/stdc++.h>
    #define ll long long
    #define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
    inline int max(const int &x,const int &y){return x>y?x:y;}
    inline void swap(int &x,int &y){x^=y^=x^=y;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    ll read(){
        ll res,f=1;char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=2e6+5;
    struct node{int v,l,r,d;}p[N];int fa[N],rt;
    int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    int merge(int x,int y){
    	if(!x||!y)return x|y;if(p[x].v<p[y].v)swap(x,y);
    	p[x].r=merge(p[x].r,y),fa[p[x].r]=x;
    	if(p[p[x].l].d<p[p[x].r].d)swap(p[x].l,p[x].r);p[x].d=p[p[x].r].d+1;
    	return x;
    }
    void dec(int x,int val,bool typ){
    	p[x].v-=val;if(p[x].v<0)p[x].v=0;
    	int l=p[x].l,r=p[x].r;fa[l]=l,fa[r]=r;
    	p[x].l=p[x].r=p[x].d=0,rt=merge(l,r);
    	typ?merge(find(x),rt):merge(rt,x);
    }
    int n,m,T,w,typ,x,y,sum;bool vis[N];ll k;
    void solve(){
    	n=read(),m=read();
    	fp(i,1,n)fa[i]=i,vis[i]=0,p[i].v=read(),p[i].l=p[i].r=p[i].d=0;
    	while(m--){
    		typ=read(),x=read();
    		switch(typ){
    			case 2:dec(x,p[x].v,1);break;
    			case 3:y=read(),dec(find(x),y,0);break;
    			case 4:y=read(),merge(find(x),find(y));break;
    		}
    	}
    	y=0,sum=0;fp(i,1,n)if(!vis[x=find(i)])vis[x]=1,sum+=p[x].v,y=max(y,p[x].v);
    	if(w==2)sum-=y;if(w==3)sum+=y;
    	if(!sum)printf("Gensokyo ");
    	else if(sum<=k)printf("Heaven ");
    	else printf("Hell ");
    	printf("%d
    ",sum);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	T=read(),w=read(),k=read();
    	while(T--)solve();
    	return 0;
    }
    
  • 相关阅读:
    基于HTTP协议的轻量级简单队列服务-HTTPSQS
    PHP获取客户端IP
    编译安装Memcached并使用systemctl管理
    win10利用WSL2安装docker的2种方式
    如何提升前端基建的效能价值?
    如何衡量前端基建的效能价值?
    从面向对象角度看前端工程体系
    「前端工程化」该怎么理解?
    跨端方案的三大困境
    React 17 要来了,非常特别的一版
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10043757.html
Copyright © 2011-2022 走看看