bzoj 2809 dispatching
一开始没想出来,想大概需要维护一下工资单调递增然后求和什么的,后来一查发现是splay启发式合并,于是我赶紧先去做了一下Neverland那个题,发下什么启发式合并其实就是暴力合并......表示无奈。
这个题居然这么轻松就写过了,而且还是1A,代码居然比Neverland还短......就是维护一下sum工资和就行了,查找的话类比寻找第k小的数。
dispatching
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #define maxn 200000 7 using namespace std; 8 9 int c[maxn][2]; 10 int t[maxn],fir[maxn],next[maxn],fa[maxn],key[maxn],size[maxn],q[maxn]; 11 long long sum[maxn],able[maxn]; 12 int n,m,tot,root; 13 long long ans; 14 15 inline void update(int x) 16 { 17 if (!x) return; 18 size[x]=size[c[x][0]]+size[c[x][1]]+1; 19 sum[x]=sum[c[x][0]]+sum[c[x][1]]+key[x]; 20 } 21 22 inline void rotate(int x) 23 { 24 int y=fa[x],z=fa[y]; 25 int p=(c[y][1]==x),q=p^1; 26 if (fa[y]) 27 if (c[z][0]==y) c[z][0]=x; else c[z][1]=x; 28 fa[x]=z; fa[y]=x; fa[c[x][q]]=y; 29 c[y][p]=c[x][q]; c[x][q]=y; 30 update(y); 31 } 32 33 inline void splay(int x) 34 { 35 while (fa[x]) 36 { 37 int y=fa[x],z=fa[y]; 38 if (fa[y]) 39 if ((c[z][0]==y)xor(c[y][0]==x)) rotate(x); else rotate(y); 40 rotate(x); 41 } 42 update(x); 43 } 44 45 inline void insert(int &t,int anc,int x) 46 { 47 if (!t) 48 { 49 t=x; 50 fa[x]=anc; 51 splay(x); 52 return; 53 } 54 if (key[x]<=key[t]) insert(c[t][0],t,x); 55 else insert(c[t][1],t,x); 56 } 57 58 inline void merge(int x,int y) 59 { 60 if (size[x]>size[y]) swap(x,y); 61 splay(x); splay(y); 62 int head=0, tail=1; 63 q[0]=y; q[1]=x; 64 while (head<tail) 65 { 66 int now=q[++head]; 67 if (c[now][0]) q[++tail]=c[now][0]; 68 if (c[now][1]) q[++tail]=c[now][1]; 69 c[now][0]=c[now][1]=0; 70 insert(q[head-1],0,now); 71 } 72 } 73 74 inline long long find(int t,int k) 75 { 76 if (!t) return 0; 77 if (k==sum[c[t][0]]+key[t]) return size[c[t][0]]+1; 78 if (k<sum[c[t][0]]+key[t]) return find(c[t][0],k); 79 if (k>sum[c[t][0]]+key[t]) return find(c[t][1],k-sum[c[t][0]]-key[t])+size[c[t][0]]+1; 80 } 81 82 inline void dfs(int now) 83 { 84 for (int j=fir[now];j;j=next[j]) 85 { 86 int k=t[j]; 87 dfs(k); 88 merge(k,now); 89 } 90 splay(now); 91 long long tmp=find(now,m); 92 ans=max(ans,able[now]*tmp); 93 } 94 95 inline void add(int x,int y) 96 { 97 t[++tot]=y; next[tot]=fir[x]; fir[x]=tot; 98 } 99 100 int main() 101 { 102 //freopen("dispatch.in","r",stdin); 103 scanf("%d %d",&n,&m); 104 int x,y,z; 105 for (int i=1;i<=n;i++) 106 { 107 scanf("%d %d %d",&x,&y,&z); 108 if (x) add(x,i);else root=i; 109 key[i]=y; 110 able[i]=z; 111 } 112 dfs(root); 113 printf("%lld\n",ans); 114 }
AC without art, no better than WA !