[loj3076]公园

为了方便,对题意做以下处理:

1.称"西部主题"和"科幻主题"分别为黑色和白色

2.删去题中"保证没有两条不同的道路连接同一对景点"的条件

关于题中的条件,即保证图中总存在重边、一度点或二度点(或仅剩一个点)

(具体证明参考2019年的论文,这里就省略了)

考虑对这些特殊的结构进行处理,具体如下——

对于节点$x$,将其点权$w_{x}$用一个$2\times 1$的矩阵描述,分别为$x$染黑色和白色的美观度

对于边$(x,y)$,将其边权$v_{(x,y)}$用一个$4\times 1$的矩阵描述,分别为$x$染黑色$y$染黑色、$x$染黑色$y$染白色、$x$染白色$y$染黑色和$x$染白色$y$染白色时这条边的美观度

关于重边,假设两边分别为$e_{1}$和$e_{2}$,构造边权之间的二元运算$\oplus$,使得合并后新边边权为$v_{e_{1}}\oplus v_{e_{2}}$

关于一度点,假设该点为$x$、出边为$e$、出边终点为$y$,构造点权、边权和点权之间的三元运算$\odot$(结果为点权),使得合并后新点点权为$\odot\left(w_{x},v_{e},w_{y}\right)$

关于二度点,假设该点为$x$,出边分别为$e_{1}$和$e_{2}$,构造边权、点权和边权之间的三元运算$\otimes$(结果为边权),使得合并后新边边权为$\otimes(v_{e_{1}},w_{x},v_{e_{2}})$(方向为从$e_{1}$终点指向$e_{2}$终点)

另外,注意到每一条边仅存储了一个方向,可能会导致无法合并,因此还需要一个反向操作

为了让其更形式化,构造边权的一元运算$R$​,使得$R(w_{e})$为将$e$反向后的边边权

(为了让阅读更连贯,具体的构造都放在文末)

由此,可以得到一棵表达式树,树上的叶子节点存储初始的点权和边权,非叶子节点存储一种运算(上述四种之一),运算后根节点必然是点权且将两值取$\max$即为答案

类似于动态dp,将其树链剖分,问题即是要修改某个位置的值后能快速维护其重链顶端的值

提取一个类似于矩阵乘法的运算$*$,满足$A*B=C$,其中$A,B$和$C$分别是$a\times b,b\times c$和$a\times c$的矩阵,并且有$C_{i,j}=\max_{k=1}^{b}(a_{i,k}+b_{k,j})$,显然其与矩阵乘法一样满足结合律

通过这个运算,那么在这之前的四种运算中,每次运算结果都可以看作其中任意一个参与运算的变量左$*$一个矩阵(这个矩阵由剩下的参与运算的变量确定)

由此,在每个位置上记录需要左$*$的矩阵,根据$*$的结合律即可用线段树维护(注意每次要从链尾算起)

总复杂度为$o(n\log^{2}n)$,可以通过

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 100005
  4 #define M 1000005
  5 #define ll long long
  6 #define L (k<<1)
  7 #define R (L+1)
  8 #define mid (l+r>>1)
  9 int n,m,V,q,x,y,num[20],op[M],v[M][3];
 10 struct matrix{
 11     int n,m;
 12     ll a[4][4];
 13     bool operator != (const matrix &k)const{
 14         if ((n!=k.n)||(m!=k.m))return 1;
 15         for(int i=0;i<k.n;i++)
 16             for(int j=0;j<m;j++)
 17                 if (a[i][j]!=k.a[i][j])return 1;
 18         return 0;
 19     }
 20     matrix(){
 21         n=m=0;
 22         memset(a,-0x3f,sizeof(a));
 23     }
 24 }w[M],trans[M];
 25 int read(){
 26     int x=0;
 27     char c=getchar();
 28     while ((c<'0')||(c>'9'))c=getchar();
 29     while ((c>='0')&&(c<='9')){
 30         x=x*10+c-'0';
 31         c=getchar();
 32     }
 33     return x;
 34 }
 35 void write(ll n,char c='\0'){
 36     while (n){
 37         num[++num[0]]=n%10;
 38         n/=10;
 39     }
 40     if (!num[0])putchar('0');
 41     while (num[0])putchar(num[num[0]--]+'0');
 42     putchar(c);
 43 }
 44 matrix mul(matrix a,matrix b){
 45     matrix ans;
 46     ans.n=a.n,ans.m=b.m;
 47     for(int i=0;i<a.n;i++)
 48         for(int j=0;j<a.m;j++)
 49             for(int k=0;k<b.m;k++)ans.a[i][k]=max(ans.a[i][k],a.a[i][j]+b.a[j][k]);
 50     return ans;
 51 }
 52 matrix get(int type,matrix a=matrix(),matrix b=matrix()){
 53     matrix ans;
 54     if (type==1){
 55         ans.n=ans.m=4;
 56         for(int i=0;i<4;i++)ans.a[i][i]=a.a[i][0];
 57     }
 58     if (type==2){
 59         ans.n=ans.m=2;
 60         ans.a[0][0]=a.a[0][0]+b.a[0][0];
 61         ans.a[0][1]=a.a[2][0]+b.a[0][0];
 62         ans.a[1][0]=a.a[1][0]+b.a[1][0];
 63         ans.a[1][1]=a.a[3][0]+b.a[1][0];
 64     }
 65     if (type==3){
 66         ans.n=2,ans.m=4;
 67         ans.a[0][0]=a.a[0][0]+b.a[0][0];
 68         ans.a[0][2]=a.a[1][0]+b.a[0][0];
 69         ans.a[1][1]=a.a[0][0]+b.a[1][0];
 70         ans.a[1][3]=a.a[1][0]+b.a[1][0];
 71     }
 72     if (type==4){
 73         ans.n=ans.m=2;
 74         ans.a[0][0]=max(a.a[0][0]+b.a[0][0],a.a[1][0]+b.a[2][0]);
 75         ans.a[1][1]=max(a.a[0][0]+b.a[1][0],a.a[1][0]+b.a[3][0]);
 76     }
 77     if (type==5){
 78         ans.n=ans.m=4;
 79         ans.a[0][0]=ans.a[2][1]=a.a[0][0]+b.a[0][0];
 80         ans.a[0][2]=ans.a[2][3]=a.a[1][0]+b.a[2][0];
 81         ans.a[1][0]=ans.a[3][1]=a.a[0][0]+b.a[1][0];
 82         ans.a[1][2]=ans.a[3][3]=a.a[1][0]+b.a[3][0];
 83     }
 84     if (type==6){
 85         ans.n=4,ans.m=2;
 86         ans.a[0][0]=a.a[0][0]+b.a[0][0];
 87         ans.a[0][1]=a.a[2][0]+b.a[2][0];
 88         ans.a[1][0]=a.a[0][0]+b.a[1][0];
 89         ans.a[1][1]=a.a[2][0]+b.a[3][0];
 90         ans.a[2][0]=a.a[1][0]+b.a[0][0];
 91         ans.a[2][1]=a.a[3][0]+b.a[2][0];
 92         ans.a[3][0]=a.a[1][0]+b.a[1][0];
 93         ans.a[3][1]=a.a[3][0]+b.a[3][0];
 94     }
 95     if (type==7){
 96         ans.n=ans.m=4;
 97         ans.a[0][0]=ans.a[1][1]=a.a[0][0]+b.a[0][0];
 98         ans.a[0][2]=ans.a[1][3]=a.a[2][0]+b.a[1][0];
 99         ans.a[2][0]=ans.a[3][1]=a.a[1][0]+b.a[0][0];
100         ans.a[2][2]=ans.a[3][3]=a.a[3][0]+b.a[1][0];
101     }
102     if (type==8){
103         ans.n=ans.m=4;
104         ans.a[0][0]=ans.a[1][2]=ans.a[2][1]=ans.a[3][3]=0;
105     }
106     return ans;
107 }
108 namespace Graph{
109     int vis[M],f[M];
110     queue<int>q;
111     set<int>S[N];
112     map<int,int>mat[N];
113     void add(int x,int y,int z);
114     void del(int x,int y){
115         mat[x][y]=0,S[x].erase(y),S[y].erase(x);
116     }
117     void Multi(int x,int y,int z){
118         int k=mat[x][y];
119         del(x,y);
120         trans[k]=get(1,w[z]),trans[z]=get(1,w[k]);
121         w[++V]=mul(trans[k],w[k]);
122         op[V]=1,v[V][0]=k,v[V][1]=z;
123         add(x,y,V);
124     }
125     void One(int x,int y){
126         int k=mat[x][y];
127         del(x,y);
128         trans[f[x]]=get(2,w[k],w[f[y]]);
129         trans[k]=get(3,w[f[x]],w[f[y]]);
130         trans[f[y]]=get(4,w[f[x]],w[k]);
131         w[++V]=mul(trans[k],w[k]);
132         op[V]=2,v[V][0]=f[x],v[V][1]=k,v[V][2]=f[y];
133         f[y]=V;
134         if (S[y].size()<=2)q.push(y);
135     }
136     void Two(int k,int x,int y){
137         int xx=mat[k][x],yy=mat[k][y];
138         del(k,x),del(k,y);
139         trans[xx]=get(5,w[f[k]],w[yy]);
140         trans[f[k]]=get(6,w[xx],w[yy]);
141         trans[yy]=get(7,w[xx],w[f[k]]);
142         w[++V]=mul(trans[f[k]],w[f[k]]);
143         op[V]=3,v[V][0]=xx,v[V][1]=f[k],v[V][2]=yy;
144         add(x,y,V);
145     }
146     void Rev(int x,int y){
147         int k=mat[x][y];
148         mat[x][y]=0,S[x].erase(y),S[y].erase(x);
149         trans[k]=get(8);
150         w[++V]=mul(trans[k],w[k]); 
151         op[V]=4,v[V][0]=k;
152         add(y,x,V);
153     }
154     void add(int x,int y,int z){
155         if (mat[y][x])Rev(y,x);
156         if (mat[x][y]){
157             Multi(x,y,z);
158             return;
159         }
160         mat[x][y]=z,S[x].insert(y),S[y].insert(x);
161         if (S[x].size()<=2)q.push(x);
162         if (S[y].size()<=2)q.push(y); 
163     }
164     void build(){
165         while (!q.empty())q.pop();
166         for(int i=1;i<=n;i++){
167             f[i]=i;
168             if (S[i].size()<=2)q.push(i);
169         }
170         while (!q.empty()){
171             int k=q.front();
172             q.pop();
173             if ((vis[k])||(!S[k].size()))continue;
174             vis[k]=1;
175             if (S[k].size()==1){
176                 int x=(*S[k].begin());
177                 if (mat[x][k])Rev(x,k);
178                 One(k,x);
179             }
180             else{
181                 int x=(*S[k].begin()),y=(*++S[k].begin());
182                 if (mat[x][k])Rev(x,k);
183                 if (mat[y][k])Rev(y,k);
184                 Two(k,x,y);
185             }
186         }
187     }
188 };
189 namespace Tree{
190     int son[5]={0,2,3,3,1},fa[M],sz[M],mx[M],dfn[M],top[M],tail[M];
191     matrix f[M<<2];
192     void update(int k,int l,int r,int x,matrix y){
193         if (l==r){
194             f[k]=y;
195             return;
196         }
197         if (x<=mid)update(L,l,mid,x,y);
198         else update(R,mid+1,r,x,y);
199         f[k]=mul(f[L],f[R]);
200     }
201     matrix query(int k,int l,int r,int x,int y){
202         if ((x<=l)&&(r<=y))return f[k];
203         if (y<=mid)return query(L,l,mid,x,y);
204         if (x>mid)return query(R,mid+1,r,x,y);
205         return mul(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
206     }
207     void dfs1(int k,int f){
208         fa[k]=f,sz[k]=1;
209         for(int i=0;i<son[op[k]];i++){
210             dfs1(v[k][i],k);
211             sz[k]+=sz[v[k][i]];
212             if (sz[v[k][i]]>sz[mx[k]])mx[k]=v[k][i];
213         }
214     }
215     void dfs2(int k,int f,int t){
216         dfn[k]=++dfn[0],top[k]=t;
217         if (f)update(1,1,V,dfn[k],trans[k]);
218         if (!mx[k])tail[k]=k;
219         else{
220             dfs2(mx[k],k,t);
221             tail[k]=tail[mx[k]];
222         }
223         for(int i=0;i<son[op[k]];i++)
224             if (v[k][i]!=mx[k])dfs2(v[k][i],k,v[k][i]);
225     }
226     void build(){
227         dfs1(V,0);
228         dfs2(V,0,V);
229     }
230     void update(int k){
231         while (1){
232             k=top[k];
233             if (k!=tail[k])w[k]=mul(query(1,1,V,dfn[k]+1,dfn[tail[k]]),w[tail[k]]);
234             if (k==V)return;
235             k=fa[k];
236             if (op[k]==1)trans[mx[k]]=get(1,w[v[k][0]+v[k][1]-mx[k]]);
237             else{
238                 int p=(op[k]-2)*3;
239                 if (mx[k]==v[k][0])trans[mx[k]]=get(2+p,w[v[k][1]],w[v[k][2]]);
240                 if (mx[k]==v[k][1])trans[mx[k]]=get(3+p,w[v[k][0]],w[v[k][2]]);
241                 if (mx[k]==v[k][2])trans[mx[k]]=get(4+p,w[v[k][0]],w[v[k][1]]);
242             }
243             update(1,1,V,dfn[mx[k]],trans[mx[k]]);
244         }
245     } 
246     ll query(){
247         return max(w[V].a[0][0],w[V].a[1][0]);
248     }
249 };
250 int main(){
251     n=read(),m=read(),V=n+m;
252     for(int i=1;i<=n;i++){
253         w[i].n=2,w[i].m=1;
254         for(int j=0;j<2;j++)w[i].a[j][0]=read();
255     }
256     for(int i=n+1;i<=n+m;i++){
257         x=read(),y=read();
258         w[i].n=4,w[i].m=1;
259         for(int j=0;j<2;j++)w[i].a[j][0]=w[i].a[3-j][0]=read();
260         Graph::add(x,y,i);
261     }
262     Graph::build();
263     Tree::build();
264     write(Tree::query(),'\n');
265     q=read();
266     for(int i=1;i<=q;i++){
267         x=read();
268         for(int j=0;j<2;j++)w[x].a[j][0]=read();
269         if (x>n){
270             w[x].a[2][0]=w[x].a[1][0];
271             w[x].a[3][0]=w[x].a[0][0];
272         }
273         Tree::update(x);
274         write(Tree::query(),'\n');
275     }
276     return 0;
277 } 
View Code

下面,给出每种运算的构造以及每 一个参与运算的变量需要左乘的矩阵(依次给出),以供参考

$$
\left[\begin{matrix}a_{1}\\b_{1}\\c_{1}\\d_{1}\end{matrix}\right]\oplus \left[\begin{matrix}a_{2}\\b_{2}\\c_{2}\\d_{2}\end{matrix}\right]=\left[\begin{matrix}a_{1}+a_{2}\\b_{1}+b_{2}\\c_{1}+c_{2}\\d_{1}+d_{2}\end{matrix}\right]\\\left[\begin{matrix}a_{2}&-\infty&-\infty&-\infty\\-\infty&b_{2}&-\infty&-\infty\\-\infty&-\infty&c_{2}&-\infty\\-\infty&-\infty&-\infty&d_{2}\end{matrix}\right],\left[\begin{matrix}a_{1}&-\infty&-\infty&-\infty\\-\infty&b_{1}&-\infty&-\infty\\-\infty&-\infty&c_{1}&-\infty\\-\infty&-\infty&-\infty&d_{1}\end{matrix}\right]
$$

$$
\odot\left(\left[\begin{matrix}a_{1}\\b_{1}\end{matrix}\right],\left[\begin{matrix}a_{2}\\b_{2}\\c_{2}\\d_{2}\end{matrix}\right],\left[\begin{matrix}a_{3}\\b_{3}\end{matrix}\right]\right)=\left[\begin{matrix}\max(a_{1}+a_{2},b_{1}+c_{2})+a_{3}\\\max(a_{1}+b_{2},b_{1}+d_{2})+b_{3}\end{matrix}\right]\\\left[\begin{matrix}a_{2}+a_{3}&c_{2}+a_{3}\\b_{2}+b_{3}&d_{2}+b_{3}\end{matrix}\right],\left[\begin{matrix}a_{1}+a_{3}&-\infty&b_{1}+a_{3}&-\infty\\-\infty&a_{1}+b_{3}&-\infty&b_{1}+b_{3}\end{matrix}\right],\left[\begin{matrix}\max(a_{1}+a_{2},b_{1}+c_{2})&-\infty\\-\infty&\max(a_{1}+b_{2},b_{1}+d_{2})\end{matrix}\right]
$$

$$
\otimes\left(\left[\begin{matrix}a_{1}\\b_{1}\\c_{1}\\d_{1}\end{matrix}\right],\left[\begin{matrix}a_{2}\\b_{2}\end{matrix}\right], \left[\begin{matrix}a_{3}\\b_{3}\\c_{3}\\d_{3}\end{matrix}\right]\right)=\left[\begin{matrix}\max(a_{1}+a_{2}+a_{3},c_{1}+b_{2}+c_{3})\\\max(a_{1}+a_{2}+b_{3},c_{1}+b_{2}+d_{3})\\\max(b_{1}+a_{2}+a_{3},d_{1}+b_{2}+c_{3})\\\max(b_{1}+a_{2}+b_{3},d_{1}+b_{2}+d_{3})\end{matrix}\right]\\\left[\begin{matrix}a_{2}+a_{3}&-\infty&b_{2}+c_{3}&-\infty\\a_{2}+b_{3}&-\infty&b_{2}+d_{3}&-\infty\\-\infty&a_{2}+a_{3}&-\infty&b_{2}+c_{3}\\-\infty&a_{2}+b_{3}&-\infty&b_{2}+d_{3}\end{matrix}\right],\left[\begin{matrix}a_{1}+a_{3}&c_{1}+c_{3}\\a_{1}+b_{3}&c_{1}+d_{3}\\b_{1}+a_{3}&d_{1}+c_{3}\\b_{1}+b_{3}&d_{1}+d_{3}\end{matrix}\right],\left[\begin{matrix}a_{1}+a_{2}&-\infty&c_{1}+b_{2}&-\infty\\-\infty&a_{1}+a_{2}&-\infty&c_{1}+b_{2}\\b_{1}+a_{2}&-\infty&d_{1}+b_{2}&-\infty\\-\infty&b_{1}+a_{2}&-\infty&d_{1}+b_{2}\end{matrix}\right]
$$

$$
R\left(\left[\begin{matrix}a\\b\\c\\d\end{matrix}\right]\right)=\left[\begin{matrix}a\\c\\b\\d\end{matrix}\right]\\\left[\begin{matrix}0&-\infty&-\infty&-\infty\\-\infty&-\infty&0&-\infty\\-\infty&0&-\infty&-\infty\\-\infty&-\infty&-\infty&0\end{matrix}\right]
$$

posted @ 2021-08-28 19:11  PYWBKTDA  阅读(83)  评论(0编辑  收藏  举报