Luogu P2073 送花
阿新 • • 發佈:2018-11-10
權值線段樹的模板題
然而AC後才發現,可以用\(\tt{set}\)水過……
權值線段樹類似於用線段樹來實現平衡樹的一些操作,程式碼實現還是比較方便的
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ls p<<1 #define rs p<<1|1 #define mid ((l+r)>>1) using namespace std; struct zzz{ int w,c; }tree[1000000<<2]; inline void up(int p){ //合併線段樹的資訊 tree[p].w=tree[ls].w+tree[rs].w; tree[p].c=0; if(tree[ls].w) tree[p].c+=tree[ls].c; if(tree[rs].w) tree[p].c+=tree[rs].c; } void build(int l,int r,int p){ //初始化線段樹 if(l==r){ tree[p].c=l; return ; } build(l,mid,ls); build(mid+1,r,rs); } void add(int l,int r,int p,int k,int f){ //新增一朵美麗值為f,價格為k的花 if(l==r){ if(tree[p].w) return ; tree[p].w=f; return ; } else if(k<=mid) add(l,mid,ls,k,f); else add(mid+1,r,rs,k,f); up(p); } void del1(int l,int r,int p){ //去掉最便宜的花 if(l==r){ tree[p].w=0; return ; } if(tree[ls].w) del1(l,mid,ls); else del1(mid+1,r,rs); up(p); } void del2(int l,int r,int p){ //去掉最貴的花 if(l==r){ tree[p].w=0; return ; } if(tree[rs].w) del2(mid+1,r,rs); else del2(l,mid,ls); up(p); } int read(){ int k=0,f=1; char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=-1; for(;c>='0'&&c<='9';c=getchar()) k=k*10+c-48; return k*f; } int main(){ build(1,1000001,1); int k=read(); while(k!=-1){ if(k==1){ int w=read(),c=read(); add(1,1000001,1,c,w); } if(k==3) del1(1,1000001,1); if(k==2) del2(1,1000001,1); k=read(); } cout<<tree[1].w<<" "<<tree[1].c; return 0; }