生活随笔
收集整理的這篇文章主要介紹了
【HDOJ】4358 Boring counting
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
基本思路是將樹形結(jié)構(gòu)轉(zhuǎn)線性結(jié)構(gòu),因為查詢的是從任意結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路徑。
從而將每個查詢轉(zhuǎn)換成區(qū)間,表示從該結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路徑。
離線做,按照右邊界升序排序。
利用樹狀數(shù)組區(qū)間修改。
樹狀數(shù)組表示有K個數(shù)據(jù)的數(shù)量,利用pos進(jìn)行維護(hù)。
假設(shè)現(xiàn)有的sz >= K, 那么需要對區(qū)間進(jìn)行修改。
1 /* 4358 */
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, nxt;
45 } edge_t;
46
47 typedef
struct node_t {
48 int w, id;
49
50 friend
bool operator< (
const node_t& a,
const node_t&
b) {
51 if (a.w ==
b.w)
52 return a.id <
b.id;
53 return a.w <
b.w;
54 }
55
56 } node_t;
57
58 typedef
struct ques_t {
59 int l, r, id;
60 } ques_t;
61
62 const int maxn = 1e5+
5;
63 const int maxv =
maxn;
64 const int maxe = maxv *
2;
65 int head[maxv], l;
66 edge_t E[maxe];
67 int Beg[maxn], End[maxn];
68 int val[maxn], W[maxn];
69 node_t nd[maxn];
70 vi pvc[maxn];
71 int dfs_clock;
72 int n, K;
73 int a[maxn];
74 ques_t Q[maxn];
75 int ans[maxn];
76
77 bool compq (
const ques_t& a,
const ques_t&
b) {
78 if (a.r ==
b.r)
79 return a.l <
b.l;
80 return a.r <
b.r;
81 }
82
83 void init() {
84 memset(head, -
1,
sizeof(head));
85 memset(a,
0,
sizeof(a));
86 dfs_clock = l =
0;
87 }
88
89 void addEdge(
int u,
int v) {
90 E[l].v =
v;
91 E[l].nxt =
head[u];
92 head[u] = l++
;
93
94 E[l].v =
u;
95 E[l].nxt =
head[v];
96 head[v] = l++
;
97 }
98
99 void dfs(
int u,
int fa) {
100 int v, k;
101
102 Beg[u] = ++
dfs_clock;
103 val[dfs_clock] =
W[u];
104 for (k=head[u]; k!=-
1; k=
E[k].nxt) {
105 v =
E[k].v;
106 if (v ==
fa)
107 continue;
108 dfs(v, u);
109 }
110 End[u] =
dfs_clock;
111 }
112
113 int lowest(
int x) {
114 return x & -
x;
115 }
116
117 int sum(
int x) {
118 int ret =
0;
119
120 while (x) {
121 ret +=
a[x];
122 x -=
lowest(x);
123 }
124
125 return ret;
126 }
127
128 void update(
int x,
int delta) {
129 while (x <=
n) {
130 a[x] +=
delta;
131 x +=
lowest(x);
132 }
133 }
134
135 void solve() {
136 int q;
137 int u, v;
138
139 sort(nd+
1, nd+
1+
n);
140 int cnt =
1;
141 W[nd[
1].id] =
cnt;
142 rep(i,
2, n+
1) {
143 if (nd[i].w==nd[i-
1].w) {
144 W[nd[i].id] =
cnt;
145 }
else {
146 W[nd[i].id] = ++
cnt;
147 }
148 }
149
150 dfs(
1,
0);
151
152 rep(i,
0, cnt+
1) {
153 pvc[i].clr();
154 pvc[i].pb(
0);
155 }
156
157 scanf(
"%d", &
q);
158 rep(i,
0, q) {
159 scanf(
"%d", &
u);
160 Q[i].l =
Beg[u];
161 Q[i].r =
End[u];
162 Q[i].id =
i;
163 }
164
165 sort(Q, Q+
q, compq);
166 int sz;
167 int j =
0;
168
169 rep(i,
1, n+
1) {
170 pvc[val[i]].pb(i);
171 sz = SZ(pvc[val[i]]) -
1;
172 if (sz >=
K) {
173 if (sz >
K) {
174 update(pvc[val[i]][sz-K-
1]+
1, -
1);
175 update(pvc[val[i]][sz-K]+
1,
1);
176 }
177 update(pvc[val[i]][sz-K]+
1,
1);
178 update(pvc[val[i]][sz-K+
1]+
1, -
1);
179 }
180 while (j<q && Q[j].r==
i) {
181 ans[Q[j].id] =
sum(Q[j].l);
182 ++
j;
183 }
184 }
185
186 rep(i,
0, q)
187 printf(
"%d\n", ans[i]);
188 }
189
190 int main() {
191 ios::sync_with_stdio(
false);
192 #ifndef ONLINE_JUDGE
193 freopen(
"data.in",
"r", stdin);
194 freopen(
"data.out",
"w", stdout);
195 #endif
196
197 int t;
198 int u, v;
199
200 scanf(
"%d", &
t);
201 rep(tt,
1, t+
1) {
202 init();
203 scanf(
"%d %d", &n, &
K);
204 rep(i,
1, n+
1) {
205 scanf(
"%d", &
W[i]);
206 nd[i].id =
i;
207 nd[i].w =
W[i];
208 }
209 rep(i,
1, n) {
210 scanf(
"%d %d", &u, &
v);
211 addEdge(u, v);
212 }
213 printf(
"Case #%d:\n", tt);
214 solve();
215 if (tt !=
t)
216 putchar(
'\n');
217 }
218
219 #ifndef ONLINE_JUDGE
220 printf(
"time = %d.\n", (
int)clock());
221 #endif
222
223 return 0;
224 }
數(shù)據(jù)發(fā)生器。
1 from copy
import deepcopy
2 from random
import randint, shuffle
3 import shutil
4 import string
5
6
7 def GenDataIn():
8 with open(
"data.in",
"w") as fout:
9 t = 10
10 bound = 10**9
11 fout.write(
"%d\n" %
(t))
12 for tt
in xrange(t):
13 n = randint(100, 200
)
14 K = randint(1, 5
)
15 fout.write(
"%d %d\n" %
(n, K))
16 ust = [1
]
17 vst = range(2, n+1
)
18 L =
[]
19 for i
in xrange(n):
20 x = randint(1, 100
)
21 L.append(x)
22 fout.write(
" ".join(map(str, L)) +
"\n")
23 for i
in xrange(1
, n):
24 idx = randint(0, len(ust)-1
)
25 u =
ust[idx]
26 idx = randint(0, len(vst)-1
)
27 v =
vst[idx]
28 ust.append(v)
29 vst.remove(v)
30 fout.write(
"%d %d\n" %
(u, v))
31 q =
n
32 fout.write(
"%d\n" %
(q))
33 L = range(1, n+1
)
34 shuffle(L)
35 fout.write(
"\n".join(map(str, L)) +
"\n")
36
37
38 def MovDataIn():
39 desFileName =
"F:\eclipse_prj\workspace\hdoj\data.in"
40 shutil.copyfile(
"data.in", desFileName)
41
42
43 if __name__ ==
"__main__":
44 GenDataIn()
45 MovDataIn()
?
轉(zhuǎn)載于:https://www.cnblogs.com/bombe1013/p/5191707.html
總結(jié)
以上是生活随笔為你收集整理的【HDOJ】4358 Boring counting的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。