解题:NOIP 2018 保卫王国

题面

最小支配集=全集-最大独立集

所以先把点权改成正无穷/负无穷来保证强制选/不选某个点到独立集里,然后变成了洛谷的动态DP模板

GTMDNOIP2018ZTY

  1 #include<stack>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int N=100005,M=200005,inf=1e9;
  7 int siz[N],far[N],imp[N],top[N],lst[N];
  8 int p[N],noww[M],goal[M],val[N],dfn[N]; 
  9 int n,m,t1,t2,t3,t4,t5,t6,cnt,tot; 
 10 char typ[5]; long long sum;
 11 struct a
 12 {
 13     long long mat[2][2];
 14     void Clean()
 15     {
 16         memset(mat,0,sizeof mat);
 17     }
 18 }seg[4*N],tre[N];
 19 a Matime(a x,a y)
 20 {
 21     a ret; ret.Clean();
 22     for(int i=0;i<2;i++)
 23         for(int j=0;j<2;j++)
 24             for(int k=0;k<2;k++)
 25                 ret.mat[i][j]=max(ret.mat[i][j],x.mat[i][k]+y.mat[k][j]);
 26     return ret;
 27 }
 28 void Link(int f,int t)
 29 {
 30     noww[++cnt]=p[f];
 31     goal[cnt]=t,p[f]=cnt;
 32     noww[++cnt]=p[t];
 33     goal[cnt]=f,p[t]=cnt;
 34 }
 35 void DFS(int nde,int fth)
 36 {
 37     int tmp=0;
 38     siz[nde]=1,far[nde]=fth;
 39     for(int i=p[nde];i;i=noww[i])
 40         if(goal[i]!=fth)
 41         {
 42             DFS(goal[i],nde);
 43             siz[nde]+=siz[goal[i]];
 44             if(siz[goal[i]]>tmp)
 45                 tmp=siz[goal[i]],imp[nde]=goal[i];
 46         }
 47 }
 48 void Mark(int nde,int tpp)
 49 {
 50     dfn[nde]=++tot,top[nde]=tpp;
 51     if(imp[nde])
 52     {
 53         Mark(imp[nde],tpp);
 54         for(int i=p[nde];i;i=noww[i])
 55             if(goal[i]!=imp[nde]&&goal[i]!=far[nde])
 56                 Mark(goal[i],goal[i]);
 57     }
 58     lst[nde]=imp[nde]?lst[imp[nde]]:nde;
 59 }
 60 a Query(int nde,int l,int r,int ll,int rr)
 61 {
 62     if(l>=ll&&r<=rr)
 63         return seg[nde];
 64     else 
 65     {
 66         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
 67         if(mid>=ll&&mid<rr)
 68             return Matime(Query(rs,mid+1,r,ll,rr),Query(ls,l,mid,ll,rr));
 69         if(mid>=rr) return Query(ls,l,mid,ll,rr);
 70         if(mid<ll) return Query(rs,mid+1,r,ll,rr);
 71     }
 72 }
 73 void Modify(int nde,int l,int r,int pos,a tsk)
 74 {
 75     if(l==r) seg[nde]=tsk;
 76     else
 77     {
 78         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
 79         if(pos<=mid) Modify(ls,l,mid,pos,tsk);
 80         else Modify(rs,mid+1,r,pos,tsk);
 81         seg[nde]=Matime(seg[rs],seg[ls]);
 82     }
 83 }
 84 void Prework(int nde)
 85 {
 86     stack<int> st;
 87     for(int i=nde;i;i=imp[i]) st.push(i);
 88     while(!st.empty())
 89     {
 90         int tn=st.top(); st.pop();
 91         long long x=0,y=val[tn];
 92         for(int i=p[tn];i;i=noww[i])
 93             if(goal[i]!=imp[tn]&&goal[i]!=far[tn])
 94             {
 95                 Prework(goal[i]); a mtr=tre[goal[i]];
 96                 x+=max(mtr.mat[0][0],mtr.mat[0][1]),y+=mtr.mat[0][0];
 97             }
 98         a tmp; tmp.mat[0][0]=tmp.mat[1][0]=x,tmp.mat[0][1]=y,tmp.mat[1][1]=-inf;
 99         Modify(1,1,n,dfn[tn],tmp);
100     }
101     tre[nde]=Query(1,1,n,dfn[nde],dfn[lst[nde]]);
102 }
103 void Change(int nde,long long tsk)
104 {
105     a tmp=Query(1,1,n,dfn[nde],dfn[nde]);
106     tmp.mat[0][1]+=tsk-val[nde];
107     Modify(1,1,n,dfn[nde],tmp),val[nde]=tsk;
108     for(int i=top[nde];i!=1;i=top[i])
109     {
110         int fa=far[i];
111         a tmp=Query(1,1,n,dfn[fa],dfn[fa]),tep=Query(1,1,n,dfn[i],dfn[lst[i]]);
112         tmp.mat[0][0]+=max(tep.mat[0][0],tep.mat[0][1])-max(tre[i].mat[0][0],tre[i].mat[0][1]);
113         tmp.mat[0][1]+=tep.mat[0][0]-tre[i].mat[0][0],tmp.mat[1][0]=tmp.mat[0][0];
114         Modify(1,1,n,dfn[fa],tmp),tre[i]=tep,i=fa;
115     }
116 }
117 int main()
118 {
119     scanf("%d%d%s",&n,&m,typ);
120     for(int i=1;i<=n;i++)
121         scanf("%d",&val[i]),sum+=val[i];
122     for(int i=1;i<n;i++)
123         scanf("%d%d",&t1,&t2),Link(t1,t2);
124     DFS(1,0),Mark(1,1),Prework(1);
125     while(m--)
126     {
127         scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
128         if(!t2&&!t4&&(far[t1]==t3||far[t3]==t1))
129             printf("-1
");
130         else 
131         {
132             t5=val[t1],t6=val[t3];
133             Change(t1,t2?-inf:inf);
134             Change(t3,t4?-inf:inf); 
135             a qry=Query(1,1,n,1,dfn[lst[1]]);
136             long long ans=sum-max(qry.mat[0][0],qry.mat[0][1]);
137             printf("%lld
",ans+(inf-t5)*(t2^1)+(inf-t6)*(t4^1));
138             Change(t1,t5),Change(t3,t6);
139         }
140     }
141     return 0;
142 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/10278280.html