[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 }
下面,给出每种运算的构造以及每 一个参与运算的变量需要左乘的矩阵(依次给出),以供参考
$$
\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]
$$
[loj3076]公园的更多相关文章
- UOJ #58 【WC2013】 糖果公园
题目链接:糖果公园 听说这是一道树上莫队的入门题,于是我就去写了--顺便复习了一下莫队的各种姿势. 首先,我们要在树上使用莫队,那么就需要像序列一样给树分块.这个分块的过程就是王室联邦这道题(vfle ...
- UOJ58 【WC2013】糖果公园
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- web主题公园版权信息破解:script.js加密文件
很多人会使用web主题公园网站的免费worldpress主题,但它的主题又都被加了版权信息,故意让人找不到版权信息的修改位置. 你如果去footer.php里面删除版权信息(技术支持:web主题公园) ...
- 【BZOJ-3052】糖果公园 树上带修莫队算法
3052: [wc2013]糖果公园 Time Limit: 200 Sec Memory Limit: 512 MBSubmit: 883 Solved: 419[Submit][Status] ...
- TYVJ1427 小白逛公园
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 小新经常陪小白去公园玩,也就是所谓的遛狗啦…在小新家附近有一条“公园路”,路的一边从南到北依次排着n个 ...
- [vijos P1083] 小白逛公园
不知怎地竟有种错觉此题最近做过= =目测是类似的?那道题貌似是纯动归? 本来今晚想做两道题的,一道是本题,一道是P1653疯狂的方格取数或NOI08 Employee,看看现在的时间目测这个目标又达不 ...
- 国内首家VR虚拟现实主题公园即将在北京推出
近期,美国“The VOID”.澳洲“Zero Latency”两大虚拟现实主题乐园让许多爱好者兴奋至极,门票据说都已经预约到明年2月!在如此巨大的商机面前,谁将抢到国内VR虚拟现实主题公园第一块蛋糕 ...
- bzoj 3052: [wc2013]糖果公园 带修改莫队
3052: [wc2013]糖果公园 Time Limit: 250 Sec Memory Limit: 512 MBSubmit: 506 Solved: 189[Submit][Status] ...
- Bzoj 1756: Vijos1083 小白逛公园 线段树
1756: Vijos1083 小白逛公园 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1021 Solved: 326[Submit][Statu ...
随机推荐
- go语言游戏服务端开发(四)——RPC机制
五邑隐侠,本名关健昌,12年游戏生涯. 本教程以Go语言为例. RPC指远程方法调用,游戏里引入RPC目的是降低跨进程交互的复杂度. 游戏业务设计为多go routine,一个玩家一个go routi ...
- 10.7 URI
URI: Uniform Resource Identifier 统一资源标识符 URL: Uniform Resource Locator 统一资源定位符 URN: Uniform R ...
- div标签的理解
在HTML里面,div标签是一个块状元素,不会和其他元素排列在同一行,会默认和下面的元素换行,但是如果我们需要把几个div标签排在同一行,需要怎么做? 第一种:修改块状元素 源码: <div i ...
- Windows下node-gyp查找VS安装路径简单解析
node-gyp的作用我已经不想赘述了,这里给一个我之前文章的链接:cnblogs看这里,知乎看这里.本文主要从源码入手,介绍node-gyp查找VisualStudio的过程 为了方便我们研究nod ...
- 手机淘宝轻店业务 Serverless 研发模式升级实践
一.前言 随着 Serverless 在业界各云平台落地,阿里内部 Serverless 研发平台.各种研发模式也在业务中逐步落地,如火如荼.在此契机下,淘系团队启动了轻店 Serverless 研发 ...
- 关于C、Java、Python程序运行耗时及内存用量
最近没有刷题,而是在PTA找几个题目寻找有关程序输入流问题以及各种语言在运行时对计算机消耗内存的问题, 以免很多同学解题的时候发现自己做的对但是出现运行超时的问题:针对运行内存,肯定用C/C++的同学 ...
- Docker--harbor私有仓库部署与管理
目录 一.Harbor简介 二.Harbor 部署 三.维护管理Harbor 一.Harbor简介 1.什么是Harbor ? Harbor 是 VMware 公司开源的企业级 Docker Re ...
- Java(28)集合三Map
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228436.html 博客主页:https://www.cnblogs.com/testero ...
- Java(36)IO流案例与总结
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228455.html 博客主页:https://www.cnblogs.com/testero ...
- 关于keras框架的介绍以及操作使用
Keras 是一个 Python 深度学习框架,可以方便地定义和训练几乎所有类型的深度学习模型.Keras 最开始是为研究人员开发的,其目的在于快速实验.我们可以进入网站主页 - Keras 中文文档 ...