【HDOJ】5296 Annoying problem

LCA+RMQ。挺不错的一道题目。

思路是如何通过LCA维护费用。当加入新的点u是,费用增量为
dis[u]-dis[lca(u, lower_u)] - dis[lca(u, greater_u)] + dis[lca(lower_u, greater_u)]。
若beg[u]大于当前最大值或小于最小值,lower_u=min of current, greater_u = max of current。

  1 /* 5296 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42
 43 typedef struct {
 44     int v, w, nxt;
 45 } edge_t;
 46
 47 const int maxn = 1e5+5;
 48 const int maxv = maxn;
 49 const int maxe = maxv * 2;
 50 int head[maxv];
 51 edge_t E[maxe];
 52 int dis[maxn], deep[maxn];
 53 bool visit[maxn];
 54 int beg[maxn];
 55 int V[maxn<<1], D[maxn<<1];
 56 int dp[18][maxn<<1];
 57 int l, top;
 58 sti st;
 59 sti::iterator iter;
 60
 61 void init() {
 62     st.clr();
 63     memset(visit, false, sizeof(visit));
 64     memset(head, -1, sizeof(head));
 65     l = top = 0;
 66 }
 67
 68 void addEdge(int u, int v, int w) {
 69     E[l].v = v;
 70     E[l].w = w;
 71     E[l].nxt = head[u];
 72     head[u] = l++;
 73
 74     E[l].v = u;
 75     E[l].w = w;
 76     E[l].nxt = head[v];
 77     head[v] = l++;
 78 }
 79
 80 void dfs(int u, int fa, int d, int w) {
 81     dis[u] = w;
 82     V[++top] = u;
 83     D[top] = d;
 84     beg[u] = top;
 85
 86     int v, k;
 87
 88     for (k=head[u]; k!=-1; k=E[k].nxt) {
 89         v = E[k].v;
 90         if (v == fa)
 91             continue;
 92         dfs(v, u, d+1, w+E[k].w);
 93         V[++top] = u;
 94         D[top] = d;
 95     }
 96 }
 97
 98 void init_RMQ(int n) {
 99     int i, j;
100
101     for (i=1; i<=n; ++i)
102         dp[0][i] = i;
103     for (j=1; (1<<j)<=n; ++j)
104         for (i=1; i+(1<<j)-1<=n; ++i)
105             if (D[dp[j-1][i]] < D[dp[j-1][i+(1<<(j-1))]])
106                 dp[j][i] = dp[j-1][i];
107             else
108                 dp[j][i] = dp[j-1][i+(1<<(j-1))];
109 }
110
111 int RMQ(int l, int r) {
112     if (l > r)
113         swap(l, r);
114
115     int k = 0;
116
117     while (1<<(k+1) <= r-l+1)
118         ++k;
119
120     if (D[dp[k][l]] < D[dp[k][r-(1<<k)+1]])
121         return V[dp[k][l]];
122     else
123         return V[dp[k][r-(1<<k)+1]];
124 }
125
126 int calc(int u) {
127     if (st.empty())
128         return 0;
129
130     int x, y;
131
132     iter = st.upper_bound(beg[u]);
133     if (iter == st.end() || iter==st.begin()) {
134         y = *st.rbegin();
135         x = *st.begin();
136     } else {
137         y = *iter;
138         --iter;
139         x = *iter;
140     }
141
142     int ret = 0;
143
144     ret = dis[u] - dis[RMQ(x, beg[u])] - dis[RMQ(beg[u], y)] + dis[RMQ(x, y)];
145     return ret;
146 }
147
148 int main() {
149     ios::sync_with_stdio(false);
150     #ifndef ONLINE_JUDGE
151         freopen("data.in", "r", stdin);
152         freopen("data.out", "w", stdout);
153     #endif
154
155     int t;
156     int n, q;
157     int u, v, w;
158     int op;
159     int ans;
160
161     scanf("%d", &t);
162     rep(tt, 1, t+1) {
163         scanf("%d %d", &n, &q);
164         init();
165         rep(i, 1, n) {
166             scanf("%d %d %d", &u, &v, &w);
167             addEdge(u, v, w);
168         }
169         dfs(1, 0, 0, 0);
170         init_RMQ(top);
171         printf("Case #%d:\n", tt);
172         ans = 0;
173         while (q--) {
174             scanf("%d %d", &op, &u);
175             if (op == 1) {
176                 if (!visit[u]) {
177                     visit[u] = true;
178                     ans += calc(u);
179                     st.insert(beg[u]);
180                 }
181             } else {
182                 if (visit[u]) {
183                     visit[u] = false;
184                     st.erase(beg[u]);
185                     ans -= calc(u);
186                 }
187             }
188             printf("%d\n", ans);
189         }
190     }
191
192     #ifndef ONLINE_JUDGE
193         printf("time = %d.\n", (int)clock());
194     #endif
195
196     return 0;
197 }

数据发生器。

 1 from random import randint, shuffle
 2 import shutil
 3 import string
 4
 5
 6 def GenDataIn():
 7     with open("data.in", "w") as fout:
 8         t = 10
 9         bound = 10**3
10         fout.write("%d\n" % (t))
11         for tt in xrange(t):
12             n = randint(20, 30)
13             q = randint(20, 30)
14             fout.write("%d %d\n" % (n, q))
15             ust = [1]
16             vst = range(1, n+1)
17             ust.append(1)
18             vst.remove(1)
19             un = 1
20             vn = n - 1
21             for i in xrange(1, n):
22                 uidx = randint(0, un-1)
23                 u = ust[uidx]
24                 vidx = randint(0, vn-1)
25                 v = vst[vidx]
26                 ust.append(v)
27                 vst.remove(v)
28                 un += 1
29                 vn -= 1
30                 w = randint(1, 100)
31                 fout.write("%d %d %d\n" % (u, v, w))
32             L = []
33             for i in xrange(q):
34                 op = randint(1, 2)
35                 x = randint(1, n)
36                 fout.write("%d %d\n" % (op, x))
37
38
39
40 def MovDataIn():
41     desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
42     shutil.copyfile("data.in", desFileName)
43
44
45 if __name__ == "__main__":
46     GenDataIn()
47     MovDataIn()
时间: 2024-10-19 05:28:15

【HDOJ】5296 Annoying problem的相关文章

【HDOJ】3549 Flow Problem

网络流基础题目,Edmonds_Karp可解. 1 /* 3549 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <a

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ】4956 Poor Hanamichi

基本数学题一道,看错位数,当成大数减做了,而且还把方向看反了.所求为最接近l的值. 1 #include <cstdio> 2 3 int f(__int64 x) { 4 int i, sum; 5 6 i = sum = 0; 7 while (x) { 8 if (i & 1) 9 sum -= x%10; 10 else 11 sum += x%10; 12 ++i; 13 x/=10; 14 } 15 return sum; 16 } 17 18 int main() { 1

【HDOJ】1099 Lottery

题意超难懂,实则一道概率论的题目.求P(n).P(n) = n*(1+1/2+1/3+1/4+...+1/n).结果如果可以除尽则表示为整数,否则表示为假分数. 1 #include <cstdio> 2 #include <cstring> 3 4 #define MAXN 25 5 6 __int64 buf[MAXN]; 7 8 __int64 gcd(__int64 a, __int64 b) { 9 if (b == 0) return a; 10 else return

【HDOJ】2844 Coins

完全背包. 1 #include <stdio.h> 2 #include <string.h> 3 4 int a[105], c[105]; 5 int n, m; 6 int dp[100005]; 7 8 int mymax(int a, int b) { 9 return a>b ? a:b; 10 } 11 12 void CompletePack(int c) { 13 int i; 14 15 for (i=c; i<=m; ++i) 16 dp[i]

【HDOJ】1818 It&#39;s not a Bug, It&#39;s a Feature!

状态压缩+优先级bfs. 1 /* 1818 */ 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <algorithm> 8 using namespace std; 9 10 #define MAXM 105 11 12 typedef struct {

【HDOJ】2424 Gary&#39;s Calculator

大数乘法加法,直接java A了. 1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 public static void main(String[] args) { 6 Scanner cin = new Scanner(System.in); 7 int n; 8 int i, j, k, tmp; 9 int top; 10 boolean flag; 11 int t

【HDOJ】2425 Hiking Trip

优先级队列+BFS. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 25 8 9 typedef struct node_st { 10 int x, y, t; 11 node_st() {} 12 node_st(int xx, int yy, int tt)

【HDOJ】1686 Oulipo

kmp算法. 1 #include <cstdio> 2 #include <cstring> 3 4 char src[10005], des[1000005]; 5 int next[10005], total; 6 7 void kmp(char des[], char src[]){ 8 int ld = strlen(des); 9 int ls = strlen(src); 10 int i, j; 11 12 total = i = j = 0; 13 while (