Hdu-5438 Boring counting(可持久化线段树)
来源:互联网 发布:盘古ios9.2 for mac 编辑:程序博客网 时间:2024/05/22 10:55
Description
In this problem we consider a rooted tree with N vertices. The vertices are numbered from 1 to N, and vertex 1 represents the root. There are integer weights on each vectice. Your task is to answer a list of queries, for each query, please tell us among all the vertices in the subtree rooted at vertice u, how many different kinds of weights appear exactly K times?
Input
The first line of the input contains an integer T( T<= 5 ), indicating the number of test cases.
For each test case, the first line contains two integers N and K, as described above. ( 1<= N <= 105, 1 <= K <= N )
Then come N integers in the second line, they are the weights of vertice 1 to N. ( 0 <= weight <= 109 )
For next N-1 lines, each line contains two vertices u and v, which is connected in the tree.
Next line is a integer Q, representing the number of queries. (1 <= Q <= 10 5)
For next Q lines, each with an integer u, as the root of the subtree described above.
For each test case, the first line contains two integers N and K, as described above. ( 1<= N <= 105, 1 <= K <= N )
Then come N integers in the second line, they are the weights of vertice 1 to N. ( 0 <= weight <= 109 )
For next N-1 lines, each line contains two vertices u and v, which is connected in the tree.
Next line is a integer Q, representing the number of queries. (1 <= Q <= 10 5)
For next Q lines, each with an integer u, as the root of the subtree described above.
Output
For each test case, output "Case #X:" first, X is the test number. Then output Q lines, each with a number -- the answer to each query.
Seperate each test case with an empty line.
Seperate each test case with an empty line.
Sample Input
13 11 2 21 21 33213
Sample Output
Case #1:111题意:静态问区间中出现次数为k的数字的个数。分析:通过dfs序可以将树上的问题转化为区间问题,然后可以通过将操作离线按右端点排序用每次用树状数组更新答案,同样可以用可持久化线段树转换成在线问题。#include<iostream>#include<string>#include<algorithm>#include<cstdlib>#include<cstdio>#include<set>#include<map>#include<vector>#include<cstring>#include<stack>#include<queue>#define INF 0x3f3f3f3f#define eps 1e-9#define MOD 1000000007#define MAXN 100005using namespace std;typedef long long ll;int T,n,k,q,u,v,cnt,num,dfs_cnt,w[MAXN],fh[MAXN],rd[MAXN],cd[MAXN],rt[MAXN],b[MAXN],sta[MAXN],Next[MAXN],pre[MAXN],temp[MAXN],sum[MAXN];vector <int> G[MAXN];struct Tree{ int ls,rs,lazy;}tr[MAXN*40];void Build(int &node,int l,int r){ node = ++cnt; tr[node].lazy = 0; if(l == r) return; int mid = (l+r) >> 1; Build(tr[node].ls,l,mid); Build(tr[node].rs,mid+1,r);}void deal(int &node,int x,int y,int d,int l,int r){ tr[cnt+1] = tr[node]; node = ++cnt; if(x == l && y == r) { tr[node].lazy += d; return; } int mid = (l+r) >> 1; if(y <= mid) deal(tr[node].ls,x,y,d,l,mid); else if(x <= mid) { deal(tr[node].ls,x,mid,d,l,mid); deal(tr[node].rs,mid+1,y,d,mid+1,r); } else deal(tr[node].rs,x,y,d,mid+1,r);}int Find(int node,int x,int l,int r){ if(l == r) return tr[node].lazy; int mid = (l+r)>>1; if(x <= mid) return tr[node].lazy + Find(tr[node].ls,x,l,mid); else return tr[node].lazy + Find(tr[node].rs,x,mid+1,r);}void dfs(int u,int fa){ rd[u] = ++dfs_cnt; fh[dfs_cnt] = u; for(int v : G[u]) if(v != fa) dfs(v,u); cd[u] = dfs_cnt;}void Init(){ dfs_cnt = cnt = 0; memset(rt,0,sizeof(rt)); memset(pre,0,sizeof(pre)); memset(sum,0,sizeof(sum)); memset(Next,0,sizeof(Next)); memset(temp,0,sizeof(temp)); for(int i = 1;i <= n;i++) G[i].clear();}int main(){ scanf("%d",&T); for(int t = 1;t <= T;t++) { Init(); if(t > 1) printf("\n"); printf("Case #%d:\n",t); scanf("%d%d",&n,&k); for(int i = 1;i <= n;i++) { scanf("%d",&w[i]); b[i] = w[i]; } sort(b+1,b+1+n); for(int i = 1;i <= n;i++) w[i] = lower_bound(b+1,b+1+n,w[i]) - b; for(int i = 1;i < n;i++) { scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } dfs(1,-1); Build(rt[0],1,n); for(int i = 1;i <= n;i++) { int color = w[fh[i]]; if(temp[color]) Next[temp[color]] = i; pre[i] = temp[color]; temp[color] = i; } for(int i = 1;i <= n;i++) { int color = w[fh[i]]; rt[i] = rt[i-1]; if(!sum[color]) sta[color] = i; sum[color]++; if(sum[color] == k) deal(rt[i],1,sta[color],1,1,n); else if(sum[color] > k) { deal(rt[i],pre[sta[color]]+1,sta[color],-1,1,n); deal(rt[i],sta[color]+1,Next[sta[color]],1,1,n); sta[color] = Next[sta[color]]; } } scanf("%d",&q); for(int i = 1;i <= q;i++) { scanf("%d",&num); printf("%d\n",Find(rt[cd[num]],rd[num],1,n)); } }}
0 0
- Hdu-5438 Boring counting(可持久化线段树)
- HDU 4358 Boring counting(线段树)
- hdu 4348 可持久化线段树
- *hdu 2665 (可持久化线段树)
- hdu 5820 可持久化线段树
- hdu 4358 Boring counting 线段树离线操作
- hdu 2665 Kth number ( 可持久化线段树 )
- 【HDU 4348】To the moon【可持久化线段树】
- 【可持久化线段树】【hdu 4348】To the moon
- 【HDU】4348 To the moon 【可持久化线段树】
- HDU 2665 Kth number 可持久化线段树
- hdu 4348 可持久化线段树(区间和
- HDU-2665 Kth number (可持久化线段树)
- Hdu-4348 To the moon(可持久化线段树)
- hdu 5919 Sequence II (可持久化线段树)
- HDU 3333 Turing Tree 可持久化线段树
- HDU 2665 Kth number 可持久化线段树
- 可持久化线段树
- 修改linux 终端目录颜色
- Android系统6.0获取WiFi列表为空的问题
- [事件处理] 点击同一按钮实现div的隐藏与显示切换
- jquery自动无缝轮播代码
- jQuery——merge()
- Hdu-5438 Boring counting(可持久化线段树)
- 4-9-源码反码补码、进制转化、寄存器变量、动态库dll、位运算加减
- 51Nod-1198-字符串的数量 V3
- unity3d--镜头跟随及控制(RPG游戏黑暗之光)
- iOS新升级,Xcode运行报错Could not find developer disk image(内含最新开发包)
- 常见Javase中的的网络编程
- Ubuntu14.04.5安装solr-5.0.0的两种方式
- 打印二叉树的边界节点 c++实现
- (转)去中心化:关于区块链的争论