Boring counting

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

Problem 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 <= 105)
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.

 
Sample Input
1
3 1
1 2 2
1 2
1 3
3
2
1
3
 
Sample Output
Case #1:
1
1
1
 
Author
fish@UESTC_Oblivion
 
Source
题意:给你一棵树,n个节点,以1为根,每个节点有一个权值w;
   q个询问,每个询问问,以该点为根的子树下某个权值出现k次的个数;
思路:首先w很大,用map会超时;需要离散化一下;
   处理子树问题,利用dfs序,改成区间处理;
   区间处理权值出现k次的树,利用莫队得到答案;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-14
const int N=1e5+,M=1e6+,inf=1e9+;
const ll INF=1e18+,mod=;
struct is
{
int v,nex;
}edge[N<<];
int head[N<<],edg,in[N],out[N],tot,pos[N],w[N];
vector<int>l;
int a[N],flag[N];
void add(int u,int v)
{
edg++;
edge[edg].v=v;
edge[edg].nex=head[u];
head[u]=edg;
}
void dfs(int u,int fa)
{
in[u]=++tot;
for(int i=head[u];i!=-;i=edge[i].nex)
{
int v=edge[i].v;
if(v==fa)continue;
dfs(v,u);
}
out[u]=tot;
}
struct hh
{
int l,r,now;
bool operator <(const hh b)
{
if(pos[l]!=pos[b.l])
return pos[l]<pos[b.l];
return r<b.r;
}
}p[N];
int ans[N],mp[N],z[N];
void add(int pos)
{
z[mp[a[pos]]]--;
mp[a[pos]]++;
z[mp[a[pos]]]++;
}
void del(int pos)
{
z[mp[a[pos]]]--;
mp[a[pos]]--;
z[mp[a[pos]]]++;
}
void init(int n)
{
l.clear();
memset(mp,,sizeof(mp));
memset(z,,sizeof(z));
int s=(int)(sqrt(n));
for(int i=;i<=n;i++)
pos[i]=(i-)/s+;
memset(head,-,sizeof(head));
memset(a,,sizeof(a));
edg=;
tot=;
}
int main()
{
int T,cas=;
scanf("%d",&T);
while(T--)
{
if(cas!=)
printf("\n");
int n,k;
scanf("%d%d",&n,&k);
init(n);
for(int i=;i<=n;i++)
scanf("%d",&w[i]),l.push_back(w[i]);
sort(l.begin(),l.end());
for(int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(,-);
for(int i=;i<=n;i++)
flag[in[i]]=i;
for(int i=;i<=n;i++)
a[i]=lower_bound(l.begin(),l.end(),w[flag[i]])-l.begin();
int q;
scanf("%d",&q);
for(int i=;i<=q;i++)
{
int x;
scanf("%d",&x);
p[i].l=in[x];
p[i].r=out[x];
p[i].now=i;
}
sort(p+,p++q);
int L=,R=;
for(int i=;i<=q;i++)
{
//cout<<p[i].l<<" "<<p[i].r<<" "<<p[i].now<<endl;
while(L<p[i].l)
{
del(L);
L++;
}
while(L>p[i].l)
{
L--;
add(L);
}
while(R>p[i].r)
{
del(R);
R--;
}
while(R<p[i].r)
{
R++;
add(R);
}
ans[p[i].now]=z[k];
}
printf("Case #%d:\n",cas++);
for(int i=;i<=q;i++)
printf("%d\n",ans[i]);
}
return ;
}

hdu 4358 Boring counting dfs序+莫队+离散化的更多相关文章

  1. HDU 4358 Boring counting dfs序+莫队算法

    题意:N个节点的有根树,每个节点有一个weight.有Q个查询,问在以u为根的子树中,有恰好出现了K次的weight有多少种. 这是第一次写莫队算法,之前也只是偶有耳闻. 看了别人的代码打的,还是贴上 ...

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

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

  3. hdu 4358 Boring counting 离散化+dfs序+莫队算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4358 题意:以1为根节点含有N(N <= 1e5)个结点的树,每个节点有一个权值(weight ...

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

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

  5. Codeforces 375D - Tree and Queries(dfs序+莫队)

    题目链接:http://codeforces.com/contest/351/problem/D 题目大意:n个数,col[i]对应第i个数的颜色,并给你他们之间的树形关系(以1为根),有m次询问,每 ...

  6. Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)

    题目链接  Tree and Queries 题目大意  给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...

  7. CF600E Lomsat gelral (dfs序+莫队)

    题面 题解 看到网上写了很多DSU和线段树合并的题解,笔者第一次做也是用的线段树合并,但在原题赛的时候却怕线段树合并调不出来,于是就用了更好想更好调的莫队. 这里笔者就说说莫队怎么做吧. 我们可以通过 ...

  8. HDU - 4358 Boring counting (树上启发式合并/线段树合并)

    题目链接 题意:统计树上每个结点中恰好出现了k次的颜色数. dsu on tree/线段树合并裸题. 启发式合并1:(748ms) #include<bits/stdc++.h> usin ...

  9. HDU 4358 Boring counting 树状数组+思路

    研究了整整一天orz……直接上官方题解神思路 #include <cstdio> #include <cstring> #include <cstdlib> #in ...

随机推荐

  1. 安装Arch Linux(桌面环境)

    安装xorg-server # pacman -S xorg-server xorg-server-utils xorg-xinit 安装显卡驱动 如果不知道是什么显卡,就使用以下命令查看 # lsp ...

  2. 使用 JavaScript 实现栈

    1.栈的基本操作 function Stack() { //使用数组保存栈元素 var items = []; //添加新元素到栈顶(相当于数组的末尾) this.push = function(el ...

  3. kuohao

    #include <stdio.h> int b[50]; int a[50]; int w[50]; int main() { freopen("in.txt",&q ...

  4. 如何获取imageView中当前内容的相关信息并比较?

    public class MainActivity extends Activity implements OnClickListener{ private Button button; privat ...

  5. ng-bind-html 的原素没有高度

    angularjs里绑定html元素,在页面的div里使用ng-bind-html <!-- html--> <div class="info" ng-bind- ...

  6. Linux下使用shell实现上传linux下某个目录下所有文件到ftp

    首先我们需要搞清楚单个文件怎么上传,把这个单文件上传到ftp上的实现命名为一个:upload_to_ftp_command.sh 之后,需要弄清楚怎么实现遍历一个目录下的所有文件的,把这个遍历某个目录 ...

  7. svg学习(三)rect

    <rect> 标签 <rect> 标签可用来创建矩形,以及矩形的变种. 要理解它的工作原理,请把这些代码拷贝到记事本,然后保存为 "rect1.svg" 文 ...

  8. sdutoj 2610 Boring Counting

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2610 Boring Counting Time ...

  9. 关于Block的copy和循环引用的问题

    http://blog.csdn.net/felix9/article/details/9619313 在实际开发中,发现使用Block有着比delegate和notification更简洁的优势.于 ...

  10. volatile使用详解

    Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少, ...