Description

【GDSOI2017第三轮模拟】Informatics Training(码农,平衡树)_平衡树

Solution

这题一看及时一道码农题。
肯定是平衡树。
但是c++可以直接用set做。
用给体力,颜色,每个组,序号,每组最小的刷题量开一个set。
然后搞一搞。
结果常数写的不好呗强行卡成暴力分。超了500ms,难得优化。

Code

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<set>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const int maxn=2e5+7;
int i,j,k,l,t,n,m,ans,ans1,cas,x,y,num,u,v,xiao,r;
int f[maxn],e[maxn],g[maxn],z[maxn];
bool bz[maxn];
char s[5];
struct node{
int x,w;
bool friend operator<(node x,node y){
return x.w<y.w||x.w==y.w&&x.x<y.x;
}
}p,q,o;
multiset<node>a,b,A;
multiset<int>c[maxn],d;
multiset<node>:: iterator yi,er;
multiset<int>:: iterator ii;
int gf(int x){return(!f[x])?x:f[x]=gf(f[x]);}
void gx(int x){
p.x=0,p.w=x;
yi=a.lower_bound(p);p=*yi;
}
void gy(int y){
q.x=0,q.w=y;
er=b.lower_bound(q);q=*er;
}
void he(int x,int y){
u=gf(x),v=gf(y);
if(c[u].size()>c[v].size())swap(u,v);
if(u!=v){
f[u]=v;e[0]=0;
for(ii=c[u].begin();ii!=c[u].end();ii++){
t=*ii;e[++e[0]]=t;
gy(t);o.x=t,o.w=q.x;
}
fo(i,1,e[0])c[u].erase(e[i]),c[v].insert(e[i]);
g[v]+=g[u];
}
}
int main(){
// freopen("training.in","r",stdin);
// freopen("training.out","w",stdout);
freopen("fan.in","r",stdin);
freopen("fan.out","w",stdout);
for(scanf("%d",&cas);cas;cas--){
scanf("%s",s+1);
if(s[1]=='J'){
scanf("%d%d",&x,&y);++num;
p.x=x,p.w=num;a.insert(p);
q.x=y,q.w=num;b.insert(q);
o.x=num,o.w=y;A.insert(o);
d.insert(num);
c[num].insert(num);g[num]=y;
}
else if(s[1]=='P'){
scanf("%d%d%d",&r,&x,&y);u=gf(r);g[u]+=y;
gx(r);p.x-=x;
gy(r);q.x+=y;
a.erase(yi),b.erase(er);
o.x=r,o.w=q.x-y;A.erase(o);
if(p.x>0)a.insert(p),b.insert(q),o.w+=y,A.insert(o);
else c[u].erase(r),d.erase(r),g[u]-=q.x;
}
else if(s[1]=='D'){
scanf("%d%d%d",&r,&x,&y);u=gf(r);
e[0]=0;g[u]+=c[u].size()*y;
for(ii=c[u].begin();ii!=c[u].end();ii++){
t=*ii;
gx(t);p.x-=x;
gy(t);q.x+=y;
a.erase(yi),b.erase(er);
o.x=q.w,o.w=q.x-y;A.erase(o);
if(p.x>0)a.insert(p),b.insert(q),o.w+=y,A.insert(o);
else e[++e[0]]=t,g[u]-=q.x;
}
fo(i,1,e[0])c[u].erase(e[i]),d.erase(e[i]);
}
else if(s[1]=='E'){
scanf("%d",&r);u=gf(r);
gx(r);a.erase(p);
gy(r);b.erase(q);
o.x=q.w,o.w=q.x;A.erase(o);
c[u].erase(r);d.erase(r);g[u]-=q.x;
}
else if(s[1]=='M'){
scanf("%d%d",&x,&y);
he(x,y);
}
else if(s[1]=='C'){
if(d.begin()==d.end())continue;
ii=d.begin();x=*ii;ii=d.end();ii--;y=*ii;
he(x,y);
}
else if(s[1]=='T'){
xiao=(*A.begin()).w;e[0]=z[0]=0;
while(1){
o=*A.begin();
if(d.begin()==d.end())break;
if(o.w!=xiao)break;
u=gf(o.x);
p.w=o.x,p.x=xiao;a.erase(p);
q.w=o.x,q.x=xiao;b.erase(q);
c[u].erase(o.x);d.erase(o.x);g[u]-=xiao;
A.erase(o);
}
}
else{
scanf("%d",&x);
u=gf(x);ans=ans1=0;
ans=c[u].size();
printf("%d %d\n",ans,g[u]);
}
}
}