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. if语句使用

    package yuan; public class Yuan { public static void main(String[] args) { int a = 1; int b = 8; int ...

  2. HTTP Status 404 - No result defined for action com.csdhsm.struts.action.LoginAction and result error

    智商拙计的问题,没有找到为类LoginAction和error找到定义,然后重新去struts.xml去看,我类个去,我居然把result写成了ERROR <result name=" ...

  3. [转]Vimium快捷键

    from: http://www.cppblog.com/deercoder/archive/2011/10/22/158886.html 今天下午折腾了一下Chrome下面的一个插件Vimium的使 ...

  4. switch… case 语句的用法(二)

    总结来说:switch的用法是判断case后面的表达式和switch后面的表达式是否相匹配,一旦case匹配,就会顺序执行后面的程序代码,而不管后面的case是否匹配,直到遇见break.都不匹配找d ...

  5. SharePoint表单和工作流 - Nintex篇(七)

    博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 在工作流设计面板点击Close返回到列表页面,切换到List标签,选择"Nintex Forms&qu ...

  6. C++数据结构之Stack(栈)

    stack,栈,是好比堆积木似的数据结构,从上之下堆积,取出时按"LIFO"-last int first out后进先出的规则.栈一般为线程所独有,也就是每个线程有其自有的栈,与 ...

  7. hdu 2091

    PS:PE了两次....又是这种奇怪的输出格式....两个三角形直接有空行.. 代码: #include "stdio.h" void ou(int n,char a); void ...

  8. Android弱网测试中关于网络检测的一些借鉴方法

    Android 平台下提供了一个android.net.ConnectivityManager类来监控当前的网络状态包括wifi.gprs.UMTS等.可以判断当前用户网络到底是WIFI还是移动网络, ...

  9. Nginx 安装编译配置

    ./configure --prefix=/usr/local/nginx-1.8.0 --with-http_ssl_module --with-http_spdy_module --with-ht ...

  10. 技术分享:逆向分析ATM分离器

    文章内容仅供技术交流,请勿模仿操作! 背景(作者) 每一次外出时, Elizabeth和我总是格外的小心,同时把我们身上的钱藏在特殊的皮带上面,这样还不够,我们还采取了“狡兔三窟”的方式来藏身上带的银 ...