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 }

 

posted @ 2018-11-16 08:32  Ressed  阅读(174)  评论(0编辑  收藏  举报