luogu5024 [NOIp2018]保卫王国 (动态dp)
可以直接套动态dp,但因为它询问之间相互独立,所以可以直接倍增记x转移到fa[x]的矩阵
1 #include<bits/stdc++.h> 2 #define CLR(a,x) memset(a,x,sizeof(a)) 3 using namespace std; 4 typedef long long ll; 5 typedef pair<int,int> pa; 6 const int maxn=1e5+10; 7 const ll inf=1e17; 8 9 inline ll rd(){ 10 ll x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 int N,M,p[maxn]; 17 int eg[maxn*2][2],egh[maxn],ect,fa[maxn][22],dep[maxn]; 18 ll f[maxn][2]; 19 struct Mat{ 20 int n,m;ll a[3][3]; 21 Mat(int a0=0,int a1=0,ll a2=0,ll a3=0,ll a4=0,ll a5=0){ 22 n=a0,m=a1;a[1][1]=a2,a[1][2]=a3,a[2][1]=a4,a[2][2]=a5; 23 } 24 }trans[maxn][22]; 25 26 inline Mat operator * (Mat a,Mat b){ 27 Mat re; 28 re.n=a.n,re.m=b.m; 29 for(int i=1;i<=re.n;i++){ 30 for(int j=1;j<=re.m;j++){ 31 re.a[i][j]=inf; 32 for(int k=1;k<=a.m;k++){ 33 re.a[i][j]=min(re.a[i][j],a.a[i][k]+b.a[k][j]); 34 } 35 } 36 }return re; 37 } 38 39 inline void adeg(int a,int b){ 40 eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect; 41 } 42 43 void dfs1(int x){ 44 f[x][0]=0,f[x][1]=p[x]; 45 for(int i=egh[x];i;i=eg[i][1]){ 46 int b=eg[i][0];if(b==fa[x][0]) continue; 47 fa[b][0]=x,dep[b]=dep[x]+1; 48 dfs1(b); 49 f[x][0]+=f[b][1],f[x][1]+=min(f[b][0],f[b][1]); 50 } 51 } 52 53 void dfs2(int x){ 54 if(fa[x][0]){ 55 ll s0,s1; 56 s0=f[fa[x][0]][0]-f[x][1]; 57 s1=f[fa[x][0]][1]-min(f[x][0],f[x][1]); 58 trans[x][0]=Mat(2,2,inf,s1,s0,s1); 59 for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++){ 60 fa[x][i+1]=fa[fa[x][i]][i]; 61 trans[x][i+1]=trans[x][i]*trans[fa[x][i]][i]; 62 } 63 } 64 for(int i=egh[x];i;i=eg[i][1]){ 65 int b=eg[i][0];if(b==fa[x][0]) continue; 66 dfs2(b); 67 } 68 } 69 70 inline ll update(int x,int y,Mat &fx,Mat &fy){ 71 for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){ 72 if(dep[fa[x][i]]>=dep[y]) 73 fx=fx*trans[x][i],x=fa[x][i]; 74 } 75 int lca;Mat fl; 76 if(x==y){ 77 lca=y;fl=fx; 78 if(fy.a[1][1]==inf) fl.a[1][1]=inf; 79 else if(fy.a[1][2]==inf) fl.a[1][2]=inf; 80 }else{ 81 for(int i=log2(dep[x]);i>=0;i--){ 82 if(fa[x][i]!=fa[y][i]){ 83 fx=fx*trans[x][i],fy=fy*trans[y][i]; 84 x=fa[x][i],y=fa[y][i]; 85 } 86 } 87 lca=fa[x][0]; 88 // printf("~%d %d %d %d %d %d\n",x,fx.a[1][1],fx.a[1][2],y,fy.a[1][1],fy.a[1][2]); 89 ll a0=f[lca][0]-f[x][1]-f[y][1]+fx.a[1][2]+fy.a[1][2]; 90 ll a1=f[lca][1]-min(f[x][1],f[x][0])-min(f[y][1],f[y][0])+min(fx.a[1][1],fx.a[1][2])+min(fy.a[1][1],fy.a[1][2]); 91 fl=Mat(1,2,a0,a1,0,0); 92 } 93 for(int i=log2(dep[lca]);i>=0;i--){ 94 if(fa[lca][i]){ 95 fl=fl*trans[lca][i]; 96 lca=fa[lca][i]; 97 } 98 } 99 return min(fl.a[1][1],fl.a[1][2]); 100 } 101 102 int main(){ 103 // freopen("testdata.in","r",stdin); 104 int i,j,k; 105 N=rd(),M=rd();rd(); 106 for(i=1;i<=N;i++) p[i]=rd(); 107 for(i=1;i<N;i++){ 108 int a=rd(),b=rd(); 109 adeg(a,b);adeg(b,a); 110 } 111 dep[1]=1;dfs1(1);dfs2(1); 112 for(i=1;i<=M;i++){ 113 int a=rd(),x=rd(),b=rd(),y=rd(); 114 if(dep[a]<dep[b]) swap(a,b),swap(x,y); 115 if(fa[a][0]==b&&!x&&!y){ 116 printf("-1\n");continue; 117 } 118 Mat fx,fy; 119 if(x) fx=Mat(1,2,inf,f[a][1],0,0); 120 else fx=Mat(1,2,f[a][0],inf,0,0); 121 if(y) fy=Mat(1,2,inf,f[b][1],0,0); 122 else fy=Mat(1,2,f[b][0],inf,0,0); 123 printf("%lld\n",update(a,b,fx,fy)); 124 } 125 return 0; 126 }