【伸展树】sgu311

来源:互联网 发布:华彩人生一点通 mac 编辑:程序博客网 时间:2024/06/10 20:48
很久很久(真的很久)没敲splay了,这次在比赛中居然敲了出来自己也是蛮惊讶。。。。int和long long 的问题还要注意,这个题用splay也很好想,按照物品价值为关键值建树就好。。然后我还稍微优化了一点常熟(自己原来的板子问题好大)。。。。然后就水过了,其实也挺短、、、、就是很麻烦。。。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<algorithm>#include<cstdlib>#define lc(x) tree[x].c[0]#define rc(x) tree[x].c[1]#define tsum(x) tree[x].sum#define tsn(x) tree[x].sn#define tc(x) tree[x].co#define tn(x) tree[x].n#define fa(x) tree[x].fausing namespace std;struct rec{int c[3],fa;long long sum,co,n,sn;}tree[500100];int root=0,tot=0;void splay_insert(long long x,long long y){if (x==0){if (tree[tot].co>tree[y].co) {tree[y].c[1]=tot;tree[tot].fa=y;}else {tree[y].c[0]=tot;tree[tot].fa=y;}return;}if (tree[tot].co>tree[x].co) splay_insert(tree[x].c[1],x);else splay_insert(tree[x].c[0],x);tree[x].sum=tree[tree[x].c[0]].sum+tree[tree[x].c[1]].sum+tree[x].co*tree[x].n;tree[x].sn=tree[tree[x].c[0]].sn+tree[tree[x].c[1]].sn+tree[x].n;}void updata(long long x){tree[x].sum=tree[tree[x].c[0]].sum+tree[tree[x].c[1]].sum+tree[x].co*tree[x].n;tree[x].sn=tree[tree[x].c[0]].sn+tree[tree[x].c[1]].sn+tree[x].n;}void rot(long long x,long long w){int q=fa(x);int p=fa(fa(x));if (p!=0) {if (lc(p)==q) lc(p)=x;else rc(p)=x;fa(x)=p;}else {fa(x)=0;}if (tree[x].c[w]!=0) {tree[q].c[w^1]=tree[x].c[w];fa(tree[x].c[w])=q;}else {tree[q].c[w^1]=0;}tree[x].c[w]=q;fa(q)=x;updata(q);}void splay(long long x){while (fa(x)!=0){if (lc(fa(x))==x) rot(x,1);else rot(x,0);}updata(x);}void insert(long long x,long long y){tot++;tree[tot].sum=(long long)x*y;tree[tot].n=x;tree[tot].sn=x;tree[tot].co=y;if (root==0) {root=tot;}else {splay_insert(root,0);}if (tot%200==0) {splay(tot);root=tot;}}int search(long long x,long long w){if (tsn(lc(x))+tn(x)<=w) return search(rc(x),w-(tsn(lc(x))+tn(x)));if (tsn(lc(x))>w) return search(lc(x),w);return x;}void buy_out(long long x,long long y){if (tsn(root)<=x){if (tsum(root)>y) {printf("UNHAPPY\n");return;}else {if (tsn(root)<x) printf("UNHAPPY\n");else printf("HAPPY\n");root=0;return ;}}int now=search(root,x);splay(now);root=now;long long tmp1=tsum(lc(now))+(x-tsn(lc(now)))*tc(now);long long tmp2=x-tsn(lc(now));if (tmp1>y) printf("UNHAPPY\n");else{printf("HAPPY\n");int q=lc(now);fa(q)=0;lc(now)=0;tn(now)-=tmp2;tsn(now)-=x;tsum(now)=tsum(rc(now))+tn(now)*tc(now);}}int main(){freopen("test.in","r",stdin);freopen("test.out","w",stdout);long long x;long long y;char s[30];char ch;while (scanf("%c",&ch)!=EOF){scanf("%s",s);scanf("%I64d %I64d ",&x,&y);if (ch=='A') insert(x,y);if (ch=='B') buy_out(x,y);}return 0;}

0 0