题目传送门

题意:给你一棵树, 然后树上的点都有颜色,且原来为黑,现在有2个操作,1 改变某个点的颜色, 2 询问树上的白点到u点的最短距离是多少。

题解:

这里用的还是边分治的方法。

把所有东西都抠出来, 然后每次询问的时候都访问每幅分割图的另外一侧。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define lch(x) tr[x].son[0]
 12 #define rch(x) tr[x].son[1]
 13 #define max3(a,b,c) max(a,max(b,c))
 14 #define min3(a,b,c) min(a,min(b,c))
 15 typedef pair<int,int> pll;
 16 const int inf = 0x3f3f3f3f;
 17 const LL INF = 0x3f3f3f3f3f3f3f3f;
 18 const LL mod =  (int)1e9+7;
 19 const int N = 2e5 + 100;
 20 struct Node{
 21     int head[N], to[N<<1], nt[N<<1], ct[N<<1];
 22     int tot;
 23     void init(){
 24         memset(head, -1, sizeof(head));
 25         tot = 0;
 26     }
 27     void add(int u, int v, int cost){
 28         ct[tot] = cost;
 29         to[tot] = v;
 30         nt[tot] = head[u];
 31         head[u] = tot++;
 32     }
 33 }e[2];
 34 int n, m, white[N], cut[N<<1];
 35 void rebuild(int o, int u){
 36     int ff = 0;
 37     for(int i = e[0].head[u]; ~i; i = e[0].nt[i]){
 38         int v = e[0].to[i];
 39         if(o == v) continue;
 40         if(!ff){
 41             e[1].add(u, v, 1);
 42             e[1].add(v, u, 1);
 43             ff = u;
 44         }
 45         else {
 46             ++n;
 47             e[1].add(ff, n, 0); e[1].add(n, ff, 0);
 48             e[1].add(n, v, 1); e[1].add(v, n, 1);
 49             ff = n;
 50         }
 51         rebuild(u, v);
 52     }
 53 }
 54 int sz[N], minval, id;
 55 void get_edge(int o, int u, int num){
 56     sz[u] = 1;
 57     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
 58         int v = e[1].to[i];
 59         if(v == o || cut[i>>1]) continue;
 60         get_edge(u, v, num);
 61         sz[u] += sz[v];
 62         int tmp = max(sz[v], num - sz[v]);
 63         if(tmp < minval){
 64             minval = tmp;
 65             id = i;
 66         }
 67     }
 68 }
 69 int k = 0, op;
 70 vector<pll> vc[N];
 71 priority_queue<pll, vector<pll>, greater<pll> > pq[N<<2][2];
 72 int wedge[N<<2];
 73 int mm;
 74 void dfs2(int o, int u, int w){
 75     vc[u].pb(pll(k*op, w));
 76     sz[u] = 1;
 77     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
 78         int v = e[1].to[i];
 79         if(v == o || cut[i>>1]) continue;
 80         dfs2(u, v, w + e[1].ct[i]);
 81         sz[u] += sz[v];
 82     }
 83 }
 84 void solve(int u, int num){
 85     if(num <= 1) return ;
 86     minval = inf;
 87     get_edge(0, u, num);
 88     int nid = id;
 89     cut[nid>>1] = 1;
 90     ++k;
 91     op = 1;
 92     dfs2(0, e[1].to[nid], 0);
 93     op = -1;
 94     dfs2(0, e[1].to[nid^1], 0);
 95     wedge[k] = e[1].ct[nid];
 96     solve(e[1].to[nid], sz[e[1].to[nid]]);
 97     solve(e[1].to[nid^1], sz[e[1].to[nid^1]]);
 98 }
 99 void Update(int k){
100     while(!pq[k][0].empty() && !white[pq[k][0].top().se]) pq[k][0].pop();
101     while(!pq[k][1].empty() && !white[pq[k][1].top().se]) pq[k][1].pop();
102 }
103 void setwhite(int u){
104     for(int i = 0; i < vc[u].size(); i++){
105         int k = vc[u][i].fi, w = vc[u][i].se;
106         if(k < 0) pq[-k][0].push(pll(w,u));
107         else pq[k][1].push(pll(w,u));
108         Update(abs(k));
109     }
110 }
111 void setblack(int u){
112     for(int i = 0; i < vc[u].size(); i++){
113         int k = vc[u][i].fi;
114         Update(abs(k));
115     }
116 }
117 int Find(int u){
118     int ret = inf;
119     for(int i = 0; i < vc[u].size(); i++){
120         int k = vc[u][i].fi, w = vc[u][i].se;
121         if(k < 0 && !pq[-k][1].empty())
122                 ret = min(ret, w+wedge[-k]+pq[-k][1].top().fi);
123         if(k > 0 && !pq[k][0].empty())
124             ret = min(ret, w+wedge[k]+pq[k][0].top().fi);
125     }
126     return ret;
127 }
128 int main(){
129     e[0].init(); e[1].init();
130     scanf("%d", &n);
131     int u, v;
132     for(int i = 1; i < n; i++){
133         scanf("%d%d", &u, &v);
134         e[0].add(u, v, 1); e[0].add(v, u, 1);
135     }
136     memset(white, 0, sizeof(white));
137     rebuild(0, 1);
138     solve(1, n);
139     int num = 0, op;
140     scanf("%d", &m);
141     while(m--){
142         scanf("%d%d", &op, &v);
143         if(op == 0){
144             white[v] ^= 1;
145             if(white[v]){
146                 setwhite(v);
147                 num++;
148             }
149             else {
150                 setblack(v);
151                 num--;
152             }
153         }
154         else {
155             if(num == 0) puts("-1");
156             else if(white[v]) puts("0");
157             else {
158                 printf("%d\n", Find(v));
159             }
160         }
161     }
162     return 0;
163 }

View Code

转载于:https://www.cnblogs.com/MingSD/p/9916567.html

SPOJ - QTREE5 Query on a tree V 边分治相关推荐

  1. SPOJ 375. Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 375. Query on a tree Problem code: QTREE You are given a t ...

  2. spoj 375 Query on a tree (树链剖分)

    题目链接: http://www.spoj.com/problems/QTREE/ 题意: 给一颗树,每条边有一个权值.有两种操作: 1.修改某条边的值: 2.询问a.b两点路径上边权的最大值. 分析 ...

  3. SPOJ 375 Query on a tree(线段树维护树链剖分)

    题目链接:http://www.spoj.com/problems/QTREE/ 题意:给出一个树,两种操作:(1)修改某条边的权值:(2)询问某两个顶点之间边的最大值. 思路:树的路径剖分和线段树维 ...

  4. SPOJ - QTREE Query on a tree(树链剖分+线段树)

    题目链接:点击查看 题目大意:给出一棵由n个点组成的树,再给出数个操作,每次操作分为下列几种类型: QUERY x y:询问点x-点y这条路径上的所有边权的最大值 CHANGE x y:将第x条边的权 ...

  5. spoj 375 Query on a tree

    题意:给一棵树,节点数不超过10000,有两个操作:1.询问a,b路径上最长的边长.2.把第a条边长度改为b. p.s.人生中第一个树链剖分,尼玛debug了好久好久我擦... 分析:轻重边路径剖分, ...

  6. SPOJ 375 query on a tree 树链剖分

    题意: 给一棵树型数据结构 ①支持修改边的权值      ②支持成段边权最值查询 树链剖分入门题. 树链剖分+线段树 用的notonlysuccess的线段树--不开结构体事先预处理的那种 我以前写的 ...

  7. SPOJ - QTREE2 Query on a tree II(LCA)

    题目链接:点击查看 题目大意:给出一棵无根树,每条边都有权值,接下来有数次操作,每次操作分为两种类型: DIST x y:求出点x到点y的唯一路径上的权值和 KTH x y k:求出点x到点y的唯一路 ...

  8. bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

    Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7669  Solved: 1894 [Sub ...

  9. 【SPOJ】Count On A Tree II(树上莫队)

    [SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...

最新文章

  1. 大家一起和snailren学java-(一)对象导论
  2. #1413 : Rikka with String 后缀自动机 + 二级差分
  3. 开始看 汇编语言程序设计
  4. leetcode1509. 三次操作后最大值与最小值的最小差
  5. 在无头单链表的一个非头节点前插入一个节点(C语言)
  6. Eclipse InstaSearch搜索词法 (很多并不支持)
  7. 机器学习算法-十大常用算法
  8. winpe安装win7教程
  9. 自主开发新媒体,湖南卫视封杀网络转播权
  10. 笔记本 - 常用快捷键 word 笔记
  11. 百度网盘在电脑端取消自动续费
  12. 社群发现算法--强连通和连通在关联图谱中的应用
  13. 券商卖的雪球票息高,券商赚的什么钱?(雪球原理入门)
  14. java学习笔记2(datawhale教程):运算符和表达式、流程控制、数组
  15. Cello初始化时报JGRP000014
  16. CSS_变换(transform)
  17. 在 SAP 故乡,感受「边缘智能」之变
  18. 内网渗透、三层拓扑、红队考核靶场(ack123)
  19. html 文字超出边框,CAD文字超出了表格边框怎么办?
  20. WebSocket报404错误

热门文章

  1. [转]安装和使用JD-Eclipse插件
  2. MavenAnt使用
  3. ExtJS Model数据实体模型
  4. System.Transactions深入了解
  5. Enterprise Vault 系列 [CA和DA]
  6. JavaScript 工作原理之十一-渲染引擎及性能优化小技巧
  7. OSChina 周三乱弹 ——我求婚,你敢答应吗
  8. Linux下 apache 配置 wsgi 以使用 python-flask (2016年2月)
  9. 元数据驱动设计 —— 为动态移动应用创建Web API
  10. Linking Containers Together