1. 程式人生 > >bzoj2001 [Hnoi2010]City 城市建設

bzoj2001 [Hnoi2010]City 城市建設

維護 amp while sample max ace down mes lld

Description

PS國是一個擁有諸多城市的大國,國王Louis為城市的交通建設可謂絞盡腦汁。Louis可以在某些城市之間修建道路,在不同的城市之間修建道路需要不同的花費。Louis希望建造最少的道路使得國內所有的城市連通。但是由於某些因素,城市之間修建道路需要的花費會隨著時間而改變,Louis會不斷得到某道路的修建代價改變的消息,他希望每得到一條消息後能立即知道使城市連通的最小花費總和, Louis決定求助於你來完成這個任務。

Input

文件第一行包含三個整數N,M,Q,分別表示城市的數目,可以修建的道路個數,及收到的消息個數。 接下來M行,第i+1行有三個用空格隔開的整數Xi,Yi,Zi(1≤Xi,Yi≤n, 0≤Zi≤50000000),表示在城市Xi與城市Yi之間修建道路的代價為Zi。接下來Q行,每行包含兩個數k,d,表示輸入的第k個道路的修建代價修改為d(即將Zk修改為d)。

Output

輸出包含Q行,第i行輸出得知前i條消息後使城市連通的最小花費總和。

Sample Input

5 5 3
1 2 1
2 3 2
3 4 3
4 5 4
5 1 5
1 6
1 1
5 3

Sample Output

14
10
9

HINT

【數據規模】 對於20%的數據, n≤1000,m≤6000,Q≤6000。 有20%的數據,n≤1000,m≤50000,Q≤8000,修改後的代價不會比之前的代價低。 對於100%的數據, n≤20000,m≤50000,Q≤50000。

正解:不會。

我寫了一個$CDQ$分治+$LCT$,然後只有在$bzoj$才能$AC$。。

把所有邊按照時間區間分解,然後直接做$CDQ$分治,用$LCT$動態維護最小生成樹就行了。

  1 #include <bits/stdc++.h>
  2 #define il inline
  3 #define RG register
  4 #define ll long long
  5 #define N (150005)
  6 #define ls (x<<1)
  7 #define rs (x<<1|1)
  8 #define max(a,b) (a>b ? a : b)
  9 #define swap(a,b) (tmp=a,a=b,b=tmp)
 10
#define isroot(x) (ch[fa[x]][0]!=x && ch[fa[x]][1]!=x) 11 #define makeroot(x) (access(x),splay(x),rev[x]^=1) 12 #define link(x,y) (makeroot(x),fa[x]=y) 13 #define cut(x,y) (makeroot(x),access(y),splay(y),ch[y][0]=fa[x]=0,pushup(y)) 14 #define pushdown(x) (rev[x]=0,rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,swap(ch[x][0],ch[x][1])) 15 #define insert(from,to) (g[++num]=(E){head[from],to},head[from]=num) 16 17 using namespace std; 18 19 struct data{ int mx,id; }tr[N],pt[N]; 20 struct edge{ int u,v,w,l,r; }e[N],q[N]; 21 struct E{ int nt,to; }g[20*N]; 22 23 int ch[N][2],fa[N],id[N],mx[N],val[N],rev[N],st[N],Q,n,m; 24 int head[N],que[N],b[N],t[N],f[N],sz[N],num,tot,end,tmp; 25 ll ans[N],Ans; 26 27 il int gi(){ 28 RG int x=0,q=1; RG char ch=getchar(); 29 while ((ch<0 || ch>9) && ch!=-) ch=getchar(); 30 if (ch==-) q=-1,ch=getchar(); 31 while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar(); 32 return q*x; 33 } 34 35 il void pushup(RG int x){ 36 RG int &l=ch[x][0],&r=ch[x][1]; mx[x]=val[x],id[x]=x; 37 mx[x]<mx[l]?(mx[x]=mx[l],id[x]=id[l]):0; 38 mx[x]<mx[r]?(mx[x]=mx[r],id[x]=id[r]):0; return; 39 } 40 41 il void rotate(RG int x){ 42 RG int y=fa[x],z=fa[y],k=ch[y][0]==x,&v=ch[x][k]; 43 !isroot(y)?(ch[z][ch[z][1]==y]=x):0; 44 fa[x]=z,ch[y][k^1]=v,fa[v]=y; 45 v=y,fa[y]=x,pushup(y),pushup(x); return; 46 } 47 48 il void splay(RG int x){ 49 RG int top=0; st[++top]=x; 50 for (RG int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; 51 for (RG int i=top;i;--i) if (rev[st[i]]) pushdown(st[i]); 52 while (!isroot(x)){ 53 RG int y=fa[x],z=fa[y]; 54 if (!isroot(y)) rotate((ch[z][0]==y)^(ch[y][0]==x)?x:y); 55 rotate(x); 56 } 57 return; 58 } 59 60 il void access(RG int x){ 61 RG int t=0; 62 while (x) splay(x),ch[x][1]=t,pushup(x),t=x,x=fa[x]; 63 return; 64 } 65 66 il int find(RG int x){ while (x!=f[x]) x=f[x]; return x; } 67 68 il data query(RG int x,RG int y){ 69 makeroot(x),access(y),splay(y); 70 return (data){mx[y],id[y]}; 71 } 72 73 il void query(RG int x,RG int l,RG int r,RG int k){ 74 if (q[k].l<=l && r<=q[k].r){ insert(x,k); return; } 75 RG int mid=(l+r)>>1; 76 if (q[k].r<=mid) query(ls,l,mid,k); 77 else if (q[k].l>mid) query(rs,mid+1,r,k); 78 else query(ls,l,mid,k),query(rs,mid+1,r,k); 79 return; 80 } 81 82 il void add(RG int x){ 83 for (RG int i=head[x],k,x,y;i;i=g[i].nt){ 84 k=g[i].to; 85 if ((x=find(q[k].u))!=(y=find(q[k].v))){ 86 Ans+=q[k].w,link(q[k].v,k+n),link(k+n,q[k].u); 87 if (sz[x]>sz[y]) swap(x,y); sz[y]+=sz[x],f[x]=y; 88 que[++end]=k,b[end]=0,pt[end]=(data){x,y}; 89 }else{ 90 RG data res=query(q[k].v,q[k].u); 91 if (res.mx<=q[k].w) continue; res.id-=n; 92 cut(q[res.id].u,res.id+n),cut(res.id+n,q[res.id].v); 93 link(q[k].u,k+n),link(k+n,q[k].v); 94 Ans+=q[k].w-res.mx,que[++end]=k,b[end]=res.id; 95 } 96 } 97 return; 98 } 99 100 il void del(RG int top){ 101 RG int id,x,y; 102 while (end>top){ 103 id=que[end],Ans-=q[id].w,cut(q[id].u,id+n),cut(id+n,q[id].v); 104 if (!b[end]) x=pt[end].mx,y=pt[end].id,sz[y]-=sz[x],f[x]=x; 105 else id=b[end],Ans+=q[id].w,link(q[id].u,id+n),link(id+n,q[id].v); 106 --end; 107 } 108 return; 109 } 110 111 il void solve(RG int x,RG int l,RG int r){ 112 RG int tp=end; add(x); 113 if (l==r) ans[l]=Ans; else{ 114 RG int mid=(l+r)>>1; 115 solve(ls,l,mid),solve(rs,mid+1,r); 116 } 117 del(tp); return; 118 } 119 120 int main(){ 121 #ifndef ONLINE_JUDGE 122 freopen("city.in","r",stdin); 123 freopen("city.out","w",stdout); 124 #endif 125 n=gi(),m=gi(),Q=gi(); 126 for (RG int i=1;i<=n;++i) f[i]=i,sz[i]=1; 127 for (RG int i=1;i<=m;++i) 128 e[i].u=gi(),e[i].v=gi(),e[i].w=gi(),t[i]=1; 129 for (RG int i=1,k,w;i<=Q;++i){ 130 k=gi(),w=gi(),q[++tot]=e[k],e[k].w=w; 131 q[tot].l=t[k],q[tot].r=i-1,t[k]=i; 132 } 133 for (RG int i=1;i<=m;++i) 134 q[++tot]=e[i],q[tot].l=t[i],q[tot].r=Q; 135 for (RG int i=1;i<=tot;++i) val[i+n]=q[i].w; 136 for (RG int i=1;i<=tot;++i) 137 if (q[i].l<=q[i].r) query(1,1,Q,i); 138 solve(1,1,Q); 139 for (RG int i=1;i<=Q;++i) printf("%lld\n",ans[i]); 140 return 0; 141 }

bzoj2001 [Hnoi2010]City 城市建設