Boring counting

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others)
Total Submission(s): 2808    Accepted Submission(s): 826

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
 
题意:给你一个树  每个节点都有一个权值   q个询问 问x的子树中有多少种不同的权值出现了k次
题解:第一题莫队 莫队算法 正如莫涛本人而言这种方法是处理一类无修改的离线区间询问问题的  dfs序将子树的问题转换为区间问题
之后就是莫队的处理,只是一个神奇的算法,在我看来就是一种有技巧的暴力。另外还要注意对权值的离散化。PE orzz
 /******************************
code by drizzle
blog: www.cnblogs.com/hsd-/
^ ^ ^ ^
O O
******************************/
#include<bits/stdc++.h>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
#define A first
#define B second
const int mod=;
const int MOD1=;
const int MOD2=;
const double EPS=0.00000001;
typedef __int64 ll;
const ll MOD=;
const int INF=;
const ll MAX=1ll<<;
const double eps=1e-;
const double inf=~0u>>;
const double pi=acos(-1.0);
typedef double db;
typedef unsigned int uint;
typedef unsigned long long ull;
int T;
int n,k,w[],v[],vv[],x,y,q;
int in[],out[];
int pre[];
int pos[];
int re[];
int sum[];
int dfn=;
int ans;int nedge=;
struct node
{
int pre,ed;
}N[];
struct query
{
int id;
int l,r;
}M[];
void add(int st,int ed )
{
nedge++;
N[nedge].ed=ed;
N[nedge].pre=pre[st];
pre[st]=nedge;
}
void getdfs(int now,int fa)
{
in[now]=++dfn;
for(int i=pre[now];i;i=N[i].pre)
{
if(N[i].ed!=fa)
{
getdfs(N[i].ed,now);
}
}
out[now]=dfn;
}
void init()
{
nedge=;
memset(pre,,sizeof(pre));
dfn=;
ans=;
memset(sum,,sizeof(sum));
memset(N,,sizeof(N));
memset(M,,sizeof(M));
memset(re,,sizeof(re));
memset(pos,,sizeof(pos));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
memset(w,,sizeof(w));
memset(v,,sizeof(v));
memset(vv,,sizeof(vv));
}
bool cmp(struct query aa,struct query bb)
{
if(pos[aa.id]<pos[bb.id])
return true;
if(pos[aa.id]==pos[bb.id])
{
if(aa.r<bb.r)
return true;
}
return false;
}
void ad(int value)
{
if(sum[value]==k)
ans--;
sum[value]++;
if(sum[value]==k)
ans++;
}
void del(int value)
{
if(sum[value]==k)
ans--;
sum[value]--;
if(sum[value]==k)
ans++;
}
int main()
{
scanf("%d",&T);
for(int i=;i<=T;i++)
{
init();
scanf("%d %d",&n,&k);
int block=sqrt(n);
for(int j=;j<=n;j++){
scanf("%d",&w[j]);
v[j]=w[j];
}
sort(w+,w++n);
for(int j=;j<=n;j++){
v[j]=lower_bound(w+,w+n+,v[j])-w-;
}
for(int j=;j<n;j++){
scanf("%d %d",&x,&y);
add(x,y);add(y,x);
}
getdfs(,);
for(int j=;j<=n;j++)
vv[in[j]]=v[j];// 将树上的权值 下放到区间当中
scanf("%d",&q);
int exm;
for(int j=;j<=q;j++){
scanf("%d",&exm);
M[j].l=in[exm];
M[j].r=out[exm];
M[j].id=j;
pos[j]=(M[j].l)/block;//分块 处理的不是特别好
}
printf("Case #%d:\n",i);
sort(M+,M++q,cmp);
int l=, r=;//初始区间
ad(vv[++r]);
for(int j=; j<=q; j++)
{
while(r<M[j].r) ad(vv[++r]);
while(r>M[j].r) del(vv[r--]);
while(l<M[j].l) del(vv[l++]);
while(l>M[j].l) ad(vv[--l]);
re[M[j].id]=ans;
}
for(int j=;j<=q;j++)
printf("%d\n",re[j]);
if(i!=T)
printf("\n");
}
return ;
}

HDU 4358 莫队算法+dfs序+离散化的更多相关文章

  1. hdu 5145(莫队算法+逆元)

    NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  2. HDU 4638 莫队算法

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

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

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

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

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

  5. 【bzoj4940】[Ynoi2016]这是我自己的发明 DFS序+树上倍增+莫队算法

    题目描述 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1. 将树根换为 x. 2. 给出两个点 x,y,从 x 的子树中选每一个点,y 的子树中选每一个点,如果两个点点权相等, ...

  6. 【bzoj3289】Mato的文件管理 离散化+莫队算法+树状数组

    原文地址:http://www.cnblogs.com/GXZlegend/p/6805224.html 题目描述 Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份 ...

  7. NBUT 1457 莫队算法 离散化

    Sona Time Limit:5000MS     Memory Limit:65535KB     64bit IO Format: Submit Status Practice NBUT 145 ...

  8. HDU 5145 NPY and girls(莫队算法+乘法逆元)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5145 [题目大意] 给出一个数列,每次求一个区间数字的非重排列数量.答案对1e9+7取模. [题解 ...

  9. bzoj 4358 Permu - 莫队算法 - 链表

    题目传送门 需要高级权限的传送门 题目大意 给定一个全排列,询问一个区间内的值域连续的一段的长度的最大值. 考虑使用莫队算法. 每次插入一个数$x$,对值域的影响可以分成4种情况: $x - 1$, ...

随机推荐

  1. fseek ftell rewind

    下面几个函数的头文件 : <stdio.h>   fseek int fseek( FILE *stream, long offset, int origin ); 第一个参数stream ...

  2. centos下cmake安装

    步骤一.安装gcc等必备程序包(已安装则略过此步,用gcc -v检测) yum install -y gcc gcc-c++ make automake 步骤二.安装wget (已安装则略过此步) y ...

  3. Elasticsearch内存分配设置详解

    Elasticsearch默认安装后设置的内存是1GB,对于任何一个现实业务来说,这个设置都太小了.如果你正在使用这个默认堆内存配置,你的集群配置可能会很快发生问题. 这里有两种方式修改Elastic ...

  4. HandleErrorAttribute 特性使用

    public class EwHandleErrorAttribute : HandleErrorAttribute { public override void OnException(Except ...

  5. ctime、atime

    Linux系统文件有三个主要的时间属性,分别是ctime(change time, 而不是create time), atime(access time), mtime(modify time).后来 ...

  6. SQL with PL/SQL

    DDL commands --> create user / table / view / sequence alter DML --> data manipulation languag ...

  7. VS设置背景色减缓眼睛疲劳

    工具--选项--字体和颜色--(纯文本)项背景色--自定义... 色调:85 饱和度:123 亮度:205 可自己微调 字体设为10.

  8. C++全局变量在多个源代码文件中的使用

    在比较大的项目中,如果需要使用全局变量,那么就需要注意一些全局变量声明.使用不当引起的问题了. 本篇文章主要内容有两个:普通全局变量.静态全局变量.全局常量. 1.普通全局变量:假设我们需要在多个不同 ...

  9. 利用ps指令查看某个程序的进程状态

    ps -ef是查看所有的进程,然后用grep筛选出你要的信息. eg.

  10. [网络技术]网关 路由器 OSI

    tracert 1.网关与路由 关键的区别:网关是这样一个网络节点:以两个不同协议搭建的网络可以通过它进行通信.路由器是这样一种设备:它能在计算机网络间收发数据包,同时创建一个覆盖网络(overlay ...