传送门

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

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

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

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

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

//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\n",sum);
}
int main(){
// freopen("testdata.in","r",stdin);
T=read(),w=read(),k=read();
while(T--)solve();
return 0;
}

P4971 断罪者的更多相关文章

随机推荐

  1. Jmeter关联,正则表达式提取器使用2

    正则表达式的用处很多,最基础的用法 1,断言 2,传参(关联) 例子 1.http请求 2正则表达式提取,想要提取列表列中id,一遍打开列表页 如果是1,每次就会取相同的值!匹配数字的权限高于模板$0 ...

  2. [luoguP2401] 不等数列

    传送门 f[i][j]表示前i个数有j个<的方案数 #include <cstdio> #define N 1001 #define p 2015 int n, k; int f[N ...

  3. node.js 写流 createWriteStream----由浅入深

    createWriteStream 写流 基于fs模块 let fs=require("fs"); createWriteStream创建一个写流 我们先创建一个2.txt要写入的 ...

  4. Thinkphp5.0 的使用模型Model添加数据

    Thinkphp5.0 的使用模型Model添加数据 使用create()方法添加数据 $res = TestUser::create([ 'name' => 'zhao liu', 'pass ...

  5. Codeforces Round #457 (Div. 2) B

    B. Jamie and Binary Sequence (changed after round) time limit per test 2 seconds memory limit per te ...

  6. JSP的客户端请求

    以下内容引用自http://wiki.jikexueyuan.com/project/jsp/client-request.html: 当浏览器请求一个网页时,它向Web服务器发送大量的信息,信息不能 ...

  7. 【c++】【转】如何只在heap上创建对象,如何只在stack上建立对象?

    http://www.cnblogs.com/chio/archive/2007/10/23/934335.html http://blog.csdn.net/szchtx/article/detai ...

  8. centos 7 静态IP,指定DNS

    cd /etc/sysconfig/network-scripts/ 找到对应的网卡,配置并编辑 ls -l vim ifcfg-em1 配置例子: TYPE="Ethernet" ...

  9. Growth: 一个关于怎样成为优秀Web Developer 的 App

    想了想还是决定在今天公布一个预览版.这样才干持续改进.Growth是一个关于怎样成为优秀的Web Developer的APP--结合技能树.成长路线图.进阶书单.Web七日谈以及一些小測验. 它是我对 ...

  10. MFC自己主动获取网络地址函数实现----广播地址,网关,子网掩码

    void CSetSignalBoxDlg::OnBnClickedButtonGetbroadcastaddr() {       //凝视部分为还有一种获取IP方式,可略过 //char Name ...