[SDOI2014]旅行

Posted mrclr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SDOI2014]旅行相关的知识,希望对你有一定的参考价值。

嘟嘟嘟

 

总算把几个月前WA的题A了。

看到树上路径的操作,就能想到树剖。

不过要是给每一个宗教都开一个线段树的话肯定会MLE,所以我们动态开点就行啦。

然后debug了一小会儿,全是因为一些zz小错误,什么连接表遍历出边写错了,查询最大值从查询区间和复制下来却没改完……对了,这两个最好分开写,虽然代码可能会长一点,但是每一个函数里面结构还是特别清晰的。

技术分享图片
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9 #include<stack>
 10 #include<queue>
 11 using namespace std;
 12 #define enter puts("") 
 13 #define space putchar(‘ ‘)
 14 #define Mem(a, x) memset(a, x, sizeof(a))
 15 #define rg register
 16 typedef long long ll;
 17 typedef double db;
 18 const int INF = 0x3f3f3f3f;
 19 const db eps = 1e-8;
 20 const int maxn = 1e5 + 5;
 21 const int max_tre = 1e7 + 5;
 22 inline ll read()
 23 {
 24   ll ans = 0;
 25   char ch = getchar(), last =  ;
 26   while(!isdigit(ch)) {last = ch; ch = getchar();}
 27   while(isdigit(ch)) {ans = ans * 10 + ch - 0; ch = getchar();}
 28   if(last == -) ans = -ans;
 29   return ans;
 30 }
 31 inline void write(ll x)
 32 {
 33   if(x < 0) x = -x, putchar(-);
 34   if(x >= 10) write(x / 10);
 35   putchar(x % 10 + 0);
 36 }
 37 
 38 int n, q, w[maxn], c[maxn];
 39 
 40 struct Edge
 41 {
 42   int nxt, to;
 43 }e[maxn << 1];
 44 int head[maxn], ecnt = 0;
 45 void addEdge(int x, int y)
 46 {
 47   e[++ecnt] = (Edge){head[x], y};
 48   head[x] = ecnt;
 49 }
 50 
 51 int dep[maxn], fa[maxn], siz[maxn], son[maxn];
 52 void dfs1(int now, int f)
 53 {
 54   siz[now] = 1;
 55   for(int i = head[now]; i; i = e[i].nxt)
 56     {
 57       if(e[i].to == f) continue;
 58       dep[e[i].to] = dep[now] + 1;
 59       fa[e[i].to] = now;
 60       dfs1(e[i].to, now);
 61       siz[now] += siz[e[i].to];
 62       if(!son[now] || siz[son[now]] < siz[e[i].to]) son[now] = e[i].to;
 63     }
 64 }
 65 int top[maxn], dfsx[maxn], cnt = 0;
 66 void dfs2(int now, int f)
 67 {
 68   dfsx[now] = ++cnt;
 69   if(son[now])
 70     {
 71       top[son[now]] = top[now];
 72       dfs2(son[now], now);
 73     }
 74   for(int i = head[now]; i; i = e[i].nxt)
 75     {
 76       if(e[i].to == son[now] || e[i].to == f) continue;
 77       top[e[i].to] = e[i].to;
 78       dfs2(e[i].to, now);
 79     }
 80 }
 81 
 82 int ctr = 0, root[maxn], ls[max_tre], rs[max_tre], Max[max_tre], sum[max_tre];
 83 void update(int &now, int l, int r, int idx, int d)
 84 {
 85   if(!now) now = ++ctr;
 86   if(l == r) {Max[now] = sum[now] = d; return;}
 87   int mid = (l + r) >> 1;
 88   if(idx <= mid) update(ls[now], l, mid, idx, d);
 89   else update(rs[now], mid + 1, r, idx, d);
 90   sum[now] = sum[ls[now]] + sum[rs[now]];
 91   Max[now] = max(Max[ls[now]], Max[rs[now]]);
 92 }
 93 int query_Sum(int now, int l, int r, int L, int R)
 94 {
 95   if(!now) return 0;
 96   if(l == L && r == R) return sum[now];
 97   int mid = (l + r) >> 1;
 98   if(R <= mid) return query_Sum(ls[now], l, mid, L, R);
 99   else if(L > mid) return query_Sum(rs[now], mid + 1, r, L, R);
100   else return query_Sum(ls[now], l, mid, L, mid) + query_Sum(rs[now], mid + 1, r, mid + 1, R);
101 }
102 int query_Max(int now, int l, int r, int L, int R)
103 {
104   if(!now) return 0;
105   if(l == L && r == R) return Max[now];
106   int mid = (l + r) >> 1;
107   if(R <= mid) return query_Max(ls[now], l, mid, L, R);
108   else if(L > mid) return query_Max(rs[now], mid + 1, r, L, R);
109   else return max(query_Max(ls[now], l, mid, L, mid), query_Max(rs[now], mid + 1, r, mid + 1, R));
110 }
111 int queryS_path(int x, int y)
112 {
113   int col = c[x], ret = 0;
114   while(top[x] != top[y])
115     {
116       if(dep[top[x]] < dep[top[y]]) swap(x, y);
117       ret += query_Sum(root[col], 1, cnt, dfsx[top[x]], dfsx[x]);
118       x = fa[top[x]];
119     }
120   if(dfsx[x] < dfsx[y]) swap(x, y);
121   ret += query_Sum(root[col], 1, cnt, dfsx[y], dfsx[x]);
122   return ret;
123 }
124 int queryM_path(int x, int y)
125 {
126   int col = c[x], ret = 0;
127   while(top[x] != top[y])
128     {
129       if(dep[top[x]] < dep[top[y]]) swap(x, y);
130       ret = max(ret, query_Max(root[col], 1, cnt, dfsx[top[x]], dfsx[x]));
131       x = fa[top[x]];
132     }
133   if(dfsx[x] < dfsx[y]) swap(x, y);
134   ret = max(ret, query_Max(root[col], 1, cnt, dfsx[y], dfsx[x]));
135   return ret;
136 }
137 
138 char s[2];
139 
140 int main()
141 {
142   n = read(); q = read();
143   for(int i = 1; i <= n; ++i) w[i] = read(), c[i] = read();
144   for(int i = 1; i < n; ++i)
145     {
146       int x = read(), y = read();
147       addEdge(x, y); addEdge(y, x);
148     }
149   dfs1(1, 0); top[1] = 1; dfs2(1, 0);
150   for(int i = 1; i <= n; ++i) update(root[c[i]], 1, cnt, dfsx[i], w[i]);
151   for(int i = 1; i <= q; ++i)
152     {
153       scanf("%s", s); int x = read(), y = read();
154       if(s[1] == C)
155     {
156       update(root[c[x]], 1, cnt, dfsx[x], 0);
157       c[x] = y;
158       update(root[c[x]], 1, cnt, dfsx[x], w[x]);
159     }
160       else if(s[1] == W)
161     {
162       w[x] = y;
163       update(root[c[x]], 1, cnt, dfsx[x], w[x]);
164     }
165       else if(s[1] == S) write(queryS_path(x, y)), enter;
166       else write(queryM_path(x, y)), enter;
167     }
168   return 0;
169 }
View Code

 

以上是关于[SDOI2014]旅行的主要内容,如果未能解决你的问题,请参考以下文章

[Sdoi2014]旅行 题解

BZOJ3531SDOI2014旅行

[SDOI2014]旅行

bzoj3531SDOI2014旅行

bzoj3531[Sdoi2014]旅行

BZOJ3531: [Sdoi2014]旅行