基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径。
从而将每个查询转换成区间,表示从该结点到叶子结点的路径。
离线做,按照右边界升序排序。
利用树状数组区间修改。
树状数组表示有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. 深度优先算法DFS

    英雄要从H点出发,去解救位于M点的美女. 迷宫的围墙用#表示,带*号的位置表示有杀手埋伏,这些点都是不能走的, 那么英雄要最少走多少步才能解救美女呢? package myalgorithm; imp ...

  2. ldd查看可执行程序依赖的文件

    ldd 用于查看可执行程序依赖的so动态链接库文件 [root@localhost ld.so.conf.d]# ldd /usr/local/tengine/sbin/nginx linux-vds ...

  3. linux命令 chattr超级权限控件

    linux命令:chattr 1.作用 修改ext2和ext3文件系统属性(attribute),使用权限超级用户.   linux命令:chattr 1.作用修改ext2和ext3文件系统属性(at ...

  4. Java语法糖

    1.创建数组:String[] s = new String[]{"1","2","3"};//这种方法可以在不指定数组元素数量的情况下生成 ...

  5. XE5 ANDROID平台 调用 webservice

    服务端需要midas.dll   XE5对android的平台支持很有吸引力,虽然目前用来直接开发应用到安卓市场卖赚钱可能性估计不大(安卓市场目前国内好像都是免费的天下),但是对于企业应用很是很有帮助 ...

  6. mybatis随意sql语句

    mybatis的mapper.xml随意sql语句, 不管表之间存不存在关系, 都可以使用, 但注意resultMap中一定要指定查询数据返回的列 或 对象(其实就是多列封装到一个对象中) <? ...

  7. DB天气app冲刺二阶段第三天

    今天发现自己不能乖乖的按照计划来进行项目了.弄着这个然后不知不觉就弄到那边去了,结果就是哪边都弄不好,但又很纠结.还是要给自己一个计划白班才行,每次只是计划这一两天的根本不行.明天要指定一个计划白板, ...

  8. iOS开发进阶 - 使用shell脚本自动打包上传到fir.im上-b

    用fir.im测试已经好长时间了,感觉每次打包上传都很麻烦,想着是不是可以用脚本自动打包,在网上搜了一下确实有,下面总结一下如何使用脚本自动打包上传到fir.im,以及打包过程中遇到的问题和解决办法 ...

  9. asp.net MVC日志插件Log4Net学习笔记一:保存日志到本地

    log4net(Log For Net)是Apache开源的应用于.Net框架的日志记录工具,详细信息参见Apache网站.它是针对Java的log4j(Log For Java的)姊妹工具.用过lo ...

  10. 荣誉,还是苦逼?| 也议全栈工程师和DevOps

    引言 全栈工程师(本文称「全栈」开发者)和 DevOps 无疑是近期最火的词汇,无论是国外还是国内.而且火爆程度远超于想象. 全栈和 DevOps,究竟是我们的新职业方向,还是仅仅创业公司老板的心头所 ...