题意:

给出一棵树,每个顶点上有个\(2 \times 2\)的矩阵,矩阵有两种操作:

  • 顺时针旋转90°,花费是2
  • 将一种矩阵替换为另一种矩阵,花费是10

树上有一种操作,将一条路经上的所有矩阵都变为给出的矩阵,并输出最小花费。

分析:

矩阵可以分为两类共6种,一类是两个1相邻的矩阵共4种;一类是两个1在对角线的矩阵共2种。

同一类矩阵可以通过旋转操作得到,否则只能用替换。

事先计算好每种矩阵转换到另外一种矩阵的最少花费,然后树链剖分再用线段树维护就好了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int maxn = 20000 + 10;
const int maxnode = maxn * 4; void read(int& x) {
x = 0;
char c = ' ';
while(c < '0' || c > '9') c = getchar();
while('0' <= c && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
} int n, tot;
vector<int> G[maxn];
int son[maxn], sz[maxn], top[maxn], dep[maxn], fa[maxn];
int id[maxn], pos[maxn]; void dfs(int u) {
sz[u] = 1; son[u] = 0;
for(int v : G[u]) {
if(v == fa[u]) continue;
fa[v] = u;
dep[v] = dep[u] + 1;
dfs(v);
sz[u] += sz[v];
if(sz[v] > sz[son[u]]) son[u] = v;
}
} void dfs2(int u, int tp) {
id[u] = ++tot;
pos[tot] = u;
top[u] = tp;
if(son[u]) dfs2(son[u], tp);
for(int v : G[u]) {
if(v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
} int cost[6][6];
int cntv[maxnode][6], setv[maxnode]; int readMat() {
int a[4];
read(a[0]); read(a[1]); read(a[3]); read(a[2]);
for(int i = 0; i < 4; i++)
if(a[i] == 1 && a[(i+1)%4] == 1) return i;
if(a[0] == 1) return 4;
return 5;
} int h[maxn]; void pushdown(int o, int L, int R) {
if(setv[o] != -1) {
int M = (L + R) / 2;
setv[o<<1] = setv[o<<1|1] = setv[o];
for(int i = 0; i < 6; i++)
cntv[o<<1][i] = cntv[o<<1|1][i] = 0;
cntv[o<<1][setv[o]] = M - L + 1;
cntv[o<<1|1][setv[o]] = R - M;
setv[o] = -1;
}
} void pushup(int o) {
for(int i = 0; i < 6; i++)
cntv[o][i] = cntv[o<<1][i] + cntv[o<<1|1][i];
} void build(int o, int L, int R) {
if(L == R) { cntv[o][h[pos[L]]] = 1; return; }
int M = (L + R) / 2;
build(o<<1, L, M);
build(o<<1|1, M+1, R);
pushup(o);
} int q[6]; void update(int o, int L, int R, int qL, int qR, int v) {
if(qL <= L && R <= qR) {
setv[o] = v;
for(int i = 0; i < 6; i++) q[i] += cntv[o][i];
for(int i = 0; i < 6; i++) cntv[o][i] = 0;
cntv[o][v] = R - L + 1;
return;
}
pushdown(o, L, R);
int M = (L + R) / 2;
if(qL <= M) update(o<<1, L, M, qL, qR, v);
if(qR > M) update(o<<1|1, M+1, R, qL, qR, v);
pushup(o);
} void UPDATE(int u, int v, int val) {
memset(q, 0, sizeof(q));
int t1 = top[u], t2 = top[v];
while(t1 != t2) {
if(dep[t1] < dep[t2]) { swap(u, v); swap(t1, t2); }
update(1, 1, n, id[t1], id[u], val);
u = fa[t1]; t1 = top[u];
}
if(dep[u] > dep[v]) swap(u, v);
update(1, 1, tot, id[u], id[v], val);
} int main()
{
for(int i = 0; i < 6; i++)
for(int j = 0; j < 6; j++) {
if(i == j) { cost[i][j] = 0; continue; }
int a = ((i >> 2) & 1), b = ((j >> 2) & 1);
if(a ^ b) cost[i][j] = 10;
else if(!a) cost[i][j] = ((((j - i) % 4) + 4) % 4) * 2;
else cost[i][j] = 2;
} int kase; scanf("%d", &kase);
while(kase--) {
read(n);
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 1; i < n; i++) {
int u, v; read(u); read(v);
G[u].push_back(v);
G[v].push_back(u);
} sz[0] = fa[1] = 0;
dfs(1); tot = 0;
dfs2(1, 1); //build segment tree
memset(cntv, 0, sizeof(cntv));
memset(setv, -1, sizeof(setv));
for(int i = 1; i <= n; i++) h[i] = readMat();
build(1, 1, n); //Queries
int _; scanf("%d", &_);
while(_--) {
int u, v, val; read(u); read(v);
val = readMat();
UPDATE(u, v, val);
int ans = 0;
for(int i = 0; i < 6; i++) ans += q[i] * cost[i][val];
printf("%d\n", ans);
}
} return 0;
}

HDU 5614 Baby Ming and Matrix tree 树链剖分的更多相关文章

  1. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  2. POJ3237 Tree 树链剖分 边权

    POJ3237 Tree 树链剖分 边权 传送门:http://poj.org/problem?id=3237 题意: n个点的,n-1条边 修改单边边权 将a->b的边权取反 查询a-> ...

  3. hdu 5612 Baby Ming and Matrix games

    Baby Ming and Matrix games 题意: 给一个矩形,两个0~9的数字之间隔一个数学运算符(‘+’,’-‘,’*’,’/’),其中’/’表示分数除,再给一个目标的值,问是否存在从一 ...

  4. HDU 5044 Tree --树链剖分

    题意:给一棵树,两种操作: ADD1: 给u-v路径上所有点加上值k, ADD2:给u-v路径上所有边加上k,初始值都为0,问最后每个点和每条边的值,输出. 解法:树链剖分可做,剖出来如果直接用线段树 ...

  5. HDU 5840 This world need more Zhu 树链剖分+暴力

    This world need more Zhu 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5840 Description As we all ...

  6. HDU 3966:Aragorn's Story(树链剖分)

    http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意:有n个点n-1条边,每个点有一个权值,有两种操作:询问一个点上权值是多少和修改u到v这条链上的权值. ...

  7. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  8. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

  9. SPOJ Query on a tree 树链剖分 水题

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

随机推荐

  1. 洛谷P1081 开车旅行70分

    https://www.luogu.org/problem/show?pid=1081 太遗憾了明明写出来了,却把最小值初始值弄小了,从第二个点开始就不可能对了.70分! #include<io ...

  2. Java @Validated 遇到的大坑

    我在一个Controller内,在两个方法内使用@Validated,这是两个POST方法会进入的方法,这两个方法的实体类的命名(下图红框内容)不能一样,一样的话就会导致第二个在页面显示不出来错误信息 ...

  3. JSONModel 简单例子

    // ProductModel.h // JSONModel // // Created by 张国锋 on 15/7/20. // Copyright (c) 2015年 张国锋. All righ ...

  4. DOCKER启动失败Job for docker.service failed because the control process exited with error code. See "syste mctl status docker.service" and "journalctl -xe" for details.

    [root@localhost ~]# systemctl start docker Job for docker.service failed because the control process ...

  5. 告别CMD.windows终端神器conemu设置

    前言 一种刘姥姥进大观园的感觉,现在是见啥啥新鲜.因为之前不怎么接触到命令操作,平时偶尔用用cmd也没觉得什么不妥.直到现在经常调试脚本,使用git越发感觉不方便.看见同事使用的terminal绚丽夺 ...

  6. 使用SharePreferences存取数据(慕课笔记 )

    0.视频地址:http://www.imooc.com/video/3265 1.使用SharePreferences存取数据: public class MainActivity extends A ...

  7. java控制远程ssh-expect4j(一)

    github : https://github.com/wengyingjian/ssh-java-demo.git 程序写完后,ssh连接到远程服务器上需要做的步骤都是固定的,所以我们可以通过程序来 ...

  8. 打印机 Microsoft Print to PDF 所需的驱动程序 Microsoft Print To PDF 未知。登录之前,请与管理员联系,安装驱动程序。

    这个问题发生后,我觉得很疑惑,因为服务器上确定没有安装打印机.那么打印机是从哪里来的呢? 通过百度搜索,发现网上的一个帖子解答了我的疑惑.原帖地址:http://blog.chinaunix.net/ ...

  9. java.lang.ClassCastException: com.ch.hibernate.Student_$$_javassist_0 cannot be cast to javassist.util.proxy.Proxy

    利用query动态查询时,报错 java.lang.ClassCastException: com.ch.hibernate.Student_$$_javassist_0 cannot be cast ...

  10. Codeforces Round #321 (Div. 2) B. Kefa and Company (尺取)

    排序以后枚举尾部.尺取,头部单调,维护一下就好. 排序O(nlogn),枚举O(n) #include<bits/stdc++.h> using namespace std; typede ...