2020牛客多校第十場 By Rynar
阿新 • • 發佈:2020-08-10
C.Decrement on the Tree
硬生生地寫成了樹形dp,寫了160行
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define int ll typedef pair<int,int> P; const int mod=1e9+7; const int N=2e5+10; int n,m,k,z,ee; int si[N],f[N],ff[N]; ll dp[N],sz[N]; int head[N],step; int x[N],y[N]; int d[N],a[N],in[N],out[N]; int cnt=0; int ans=0; struct node1{ int val,lazy; int l,r; }tr[N<<2]; void pushup(int rt){ tr[rt].val=max(tr[rt<<1].val,tr[rt<<1|1].val); } void putdown(int rt){ if(tr[rt].lazy){ tr[rt<<1].lazy=tr[rt<<1|1].lazy=tr[rt].lazy; tr[rt<<1].val=tr[rt<<1|1].val=tr[rt].lazy; tr[rt].lazy=0; } } void build(int l,int r,int rt){ tr[rt].l=l; tr[rt].r=r; tr[rt].lazy=0; if (l==r){ tr[rt].val=a[l]; return; } int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } void update(int l,int r,int add,int rt){ if (l<=tr[rt].l&&r>=tr[rt].r){ tr[rt].lazy=add; tr[rt].val=add; return; } putdown(rt); if(l<=tr[rt<<1].r) update(l,r,add,rt<<1); if(r>=tr[rt<<1|1].l) update(l,r,add,rt<<1|1); pushup(rt); } int query(int l,int r,int rt){ if(l==tr[rt].l&&r==tr[rt].r) return tr[rt].val; putdown(rt); if(l>=tr[rt<<1|1].l) return query(l,r,rt<<1|1); else if(r<=tr[rt<<1].r) return query(l,r,rt<<1); else return max(query(l,tr[rt<<1].r,rt<<1),query(tr[rt<<1|1].l,r,rt<<1|1)); } struct node{ int to,n,cap; }e[N<<1]; void add(int x,int y,int v){ e[step].to=y; e[step].cap=v; e[step].n=head[x]; head[x]=step++; } void dfs(int x,int fa){ sz[x]=dp[x]=si[N]=0; f[x]=fa; for (int i=head[x];~i;i=e[i].n){ int v=e[i].to; if (v==fa)continue; ff[v]=i; dfs(v,x); si[x]=max(si[x],e[i].cap); if (sz[v]>e[i].cap){ ll t=max(si[v]-e[i].cap,0ll),r=sz[v]-e[i].cap; if (t>r/2)dp[x]+=t; else dp[x]+=(r+1)/2; } sz[x]+=e[i].cap; } } void update1(int x,int fa,int k,int son){ ll pp=0; int v=son; if (sz[v]>e[k*2-1].cap){ ll t=max(si[v]-e[k*2-1].cap,0ll),r=sz[v]-e[k*2-1].cap; if (t>r/2)pp-=t; else pp-=(r+1)/2; } if (x!=1&&e[ff[x]].cap<sz[x]){ ll t=max(si[x]-e[ff[x]].cap,0ll),r=sz[x]-e[ff[x]].cap; if (t>r/2)pp-=t; else pp-=(r+1)/2; } sz[x]-=ee;sz[x]+=z; e[k*2-1].cap=z;e[k*2-2].cap=z; if (sz[v]>e[k*2-1].cap){ ll t=max(si[v]-e[k*2-1].cap,0ll),r=sz[v]-e[k*2-1].cap; if (t>r/2)pp+=t; else pp+=(r+1)/2; } update(d[k],d[k],z,1); si[x]=query(in[x],out[x],1); if (x!=1&&e[ff[x]].cap<sz[x]){ ll t=max(si[x]-e[ff[x]].cap,0ll),r=sz[x]-e[ff[x]].cap; if (t>r/2)pp+=t; else pp+=(r+1)/2; } ans+=pp; } ll query1(ll x){ if (si[1]>=sz[1]/2){ return x+si[1]; } else return x+(sz[1]+1)/2; } signed main(){ int T,q; step=0; memset(head,-1,sizeof head); scanf("%lld%lld",&n,&q); for (int i=1;i<n;i++){ scanf("%lld%lld%lld",&x[i],&y[i],&z); add(x[i],y[i],z);add(y[i],x[i],z); } dfs(1,0); cnt=0; for (int i=1;i<=n;i++){ in[i]=cnt+1; for (int j=head[i];~j;j=e[j].n){ if (e[j].to==f[i])continue; d[((j|1)+1)/2]=++cnt; a[cnt]=e[j].cap; } out[i]=cnt; } build(1,cnt,1); ans=0; for (int i=1;i<=n;i++)ans+=dp[i]; printf("%lld\n",query1(ans)); while(q--){ scanf("%lld%lld",&k,&z); int now=x[k],u=y[k]; if (f[x[k]]==y[k])now=y[k],u=x[k]; ee=e[k*2-1].cap; update1(now,f[now],k,u); printf("%lld\n",query1(ans)); } return 0; }
I.Tournament
賽時沒寫出來。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=300+10; int n,m,k; int a[N][N]; signed main(){ int T; scanf("%d",&T); while (T--){ scanf("%d",&n); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=0; for (int i=2;i<=n;i++){ for (int j=1;j<=min(i-1,n-i);j++){ printf("%d %d\n",j,i); a[j][i]=1; } } for (int i=1;i<=n-1;i++){ for (int j=i+1;j<=n;j++){ if(!a[i][j])printf("%d %d\n",i,j); } } } return 0; }