基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径。
从而将每个查询转换成区间,表示从该结点到叶子结点的路径。
离线做,按照右边界升序排序。
利用树状数组区间修改。
树状数组表示有K个数据的数量,利用pos进行维护。
假设现有的sz >= K, 那么需要对区间进行修改。

 /* 4358 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 typedef struct {
int v, nxt;
} edge_t; typedef struct node_t {
int w, id; friend bool operator< (const node_t& a, const node_t& b) {
if (a.w == b.w)
return a.id < b.id;
return a.w < b.w;
} } node_t; typedef struct ques_t {
int l, r, id;
} ques_t; const int maxn = 1e5+;
const int maxv = maxn;
const int maxe = maxv * ;
int head[maxv], l;
edge_t E[maxe];
int Beg[maxn], End[maxn];
int val[maxn], W[maxn];
node_t nd[maxn];
vi pvc[maxn];
int dfs_clock;
int n, K;
int a[maxn];
ques_t Q[maxn];
int ans[maxn]; bool compq (const ques_t& a, const ques_t& b) {
if (a.r == b.r)
return a.l < b.l;
return a.r < b.r;
} void init() {
memset(head, -, sizeof(head));
memset(a, , sizeof(a));
dfs_clock = l = ;
} void addEdge(int u, int v) {
E[l].v = v;
E[l].nxt = head[u];
head[u] = l++; E[l].v = u;
E[l].nxt = head[v];
head[v] = l++;
} void dfs(int u, int fa) {
int v, k; Beg[u] = ++dfs_clock;
val[dfs_clock] = W[u];
for (k=head[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (v == fa)
continue;
dfs(v, u);
}
End[u] = dfs_clock;
} int lowest(int x) {
return x & -x;
} int sum(int x) {
int ret = ; while (x) {
ret += a[x];
x -= lowest(x);
} return ret;
} void update(int x, int delta) {
while (x <= n) {
a[x] += delta;
x += lowest(x);
}
} void solve() {
int q;
int u, v; sort(nd+, nd++n);
int cnt = ;
W[nd[].id] = cnt;
rep(i, , n+) {
if (nd[i].w==nd[i-].w) {
W[nd[i].id] = cnt;
} else {
W[nd[i].id] = ++cnt;
}
} dfs(, ); rep(i, , cnt+) {
pvc[i].clr();
pvc[i].pb();
} scanf("%d", &q);
rep(i, , q) {
scanf("%d", &u);
Q[i].l = Beg[u];
Q[i].r = End[u];
Q[i].id = i;
} sort(Q, Q+q, compq);
int sz;
int j = ; rep(i, , n+) {
pvc[val[i]].pb(i);
sz = SZ(pvc[val[i]]) - ;
if (sz >= K) {
if (sz > K) {
update(pvc[val[i]][sz-K-]+, -);
update(pvc[val[i]][sz-K]+, );
}
update(pvc[val[i]][sz-K]+, );
update(pvc[val[i]][sz-K+]+, -);
}
while (j<q && Q[j].r==i) {
ans[Q[j].id] = sum(Q[j].l);
++j;
}
} rep(i, , q)
printf("%d\n", ans[i]);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t;
int u, v; scanf("%d", &t);
rep(tt, , t+) {
init();
scanf("%d %d", &n, &K);
rep(i, , n+) {
scanf("%d", &W[i]);
nd[i].id = i;
nd[i].w = W[i];
}
rep(i, , n) {
scanf("%d %d", &u, &v);
addEdge(u, v);
}
printf("Case #%d:\n", tt);
solve();
if (tt != t)
putchar('\n');
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

数据发生器。

 from copy import deepcopy
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 10
bound = 10**9
fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(100, 200)
K = randint(1, 5)
fout.write("%d %d\n" % (n, K))
ust = [1]
vst = range(2, n+1)
L = []
for i in xrange(n):
x = randint(1, 100)
L.append(x)
fout.write(" ".join(map(str, L)) + "\n")
for i in xrange(1, n):
idx = randint(0, len(ust)-1)
u = ust[idx]
idx = randint(0, len(vst)-1)
v = vst[idx]
ust.append(v)
vst.remove(v)
fout.write("%d %d\n" % (u, v))
q = n
fout.write("%d\n" % (q))
L = range(1, n+1)
shuffle(L)
fout.write("\n".join(map(str, L)) + "\n") def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()

【HDOJ】4358 Boring counting的更多相关文章

  1. 【HDOJ】3518 Boring Counting

    后缀数组2倍增可解. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 10 ...

  2. 【HDOJ】P5056 Boring count

    题目意思是给你一个字符串和K,让你求其中有多少个字串中每个字母的出现次数不超过K次,可以等于 题目意思是很简单的,写起来也很简单,不过就是注意最后要是long long要不WA了,555~ #incl ...

  3. HDU 4358 Boring counting(莫队+DFS序+离散化)

    Boring counting Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others) ...

  4. HDOJ 题目3518 Boring counting(后缀数组,求不重叠反复次数最少为2的子串种类数)

    Boring counting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  5. HDU - 4358 Boring counting (dsu on tree)

    Boring counting: http://acm.hdu.edu.cn/showproblem.php?pid=4358 题意: 求一棵树上,每个节点的子节点中,同一颜色出现k次 的 个数. 思 ...

  6. hdu 4358 Boring counting dfs序+莫队+离散化

    Boring counting Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others) ...

  7. 【BZOJ】4358: permu 莫队算法

    [题意]给定长度为n的排列,m次询问区间[L,R]的最长连续值域.n<=50000. [算法]莫队算法 [题解]考虑莫队维护增加一个数的信息:设up[x]表示数值x往上延伸的最大长度,down[ ...

  8. (好题)树状数组+离散化+DFS序+离线/莫队 HDOJ 4358 Boring counting

    题目传送门 题意:给你一棵树,树上的每个节点都有树值,给m个查询,问以每个点u为根的子树下有多少种权值恰好出现k次. 分析:首先要对权值离散化,然后要将树形转换为线形,配上图:.然后按照右端点从小到大 ...

  9. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

随机推荐

  1. WinForms 实现气泡提示窗口

    [实例说明] 气泡提示因为他的美观又好被大多数用户所接收,用户所喜爱的就是程序员要实现的. 本实例实现了任务栏气泡提示,运行本实例,效果图如下所示: 单击提示.气泡提示就会显示,单击“关闭”气泡又会消 ...

  2. angularJs--$on、$emit和$broadcast的使用

    $emit只能向parent controller传递event与data $broadcast只能向child controller传递event与data $on用于接收event与data 例子 ...

  3. C语言宏定义取得两数的最大值和最小值

    /*本程序时为了验证用宏来做 * 两个数的大小比较的写法*/#include<stdio.h>#define MAX(x,y) ((x)<(y)?(y):(x))#define MI ...

  4. jsp日期控件My97DatePicker的使用

    My97DatePicker是一款非常灵活好用的日期控件.使用非常简单. 1.下载My97DatePicker组件包 2.将My97DatePicker包放在项目WebContent目录下 3.在页面 ...

  5. hdu 4679 Terrorist’s destroy 树形DP

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4679 题意:给定一颗树,每条边有一个权值w,问切掉哪条边之后,分成的两颗树的较大的直径*切掉边的权值最小? ...

  6. MySQL 5.6.21 最新版的安装

    上一篇 写了对于入门者来说困难的事情,博主最近装了mysql软件,下面来看看mysql的安装. 下载mysql软件安装程序,我的是在百度软件中心上下载的,选择百度是因为里面没有什么捆绑软件: 下载完了 ...

  7. 抄书(UVa714)

    Description   Before the invention of book-printing, it was very hard to make a copy of a book. All ...

  8. Oracle分析函数 — sum, rollup, cube, grouping用法

    本文通过例子展示sum, rollup, cube, grouping的用法. //首先建score表 create table score( class  nvarchar2(20), course ...

  9. Oracle查看用户所在表空间

    查看当前用户所在表空间 select username,default_tablespace from user_users; 修改用户默认表空间 alter user 用户名 default tab ...

  10. bootstrap 框架选型过程

    1.看有没有帮助文档,帮助文档的完整程度. 2.是否是我们业务需要的,花哨的功能真的有用吗? 对于偏pc端使用的系统 toggles意义不大 bootstrap和extjs的区别是什么呢? easyU ...