HDU 4358 Boring counting 树状数组+思路
研究了整整一天orz……直接上官方题解神思路

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm> using namespace std; const int MAXN = ; struct node
{
int v, next;
}; struct subTree
{
int st, ed;
}; struct Queryy
{
int i;
int st, ed;
}; int N, K, Q;
int EdgeN, TimeFlag;
node D[MAXN]; //树节点
int C[MAXN]; //树状数组
int head[MAXN];
subTree tree[MAXN]; //子树映射成线性序列之后对应的区间
Queryy qry[MAXN]; //查询信息
int weight[MAXN], addr[MAXN];
int ans[MAXN];
vector<int> pos[MAXN]; void AddEdge( int u, int v )
{
D[EdgeN].v = v;
D[EdgeN].next = head[u];
head[u] = EdgeN++;
return;
} void DFS( int cur ) //树形结构转线性结构
{
tree[ cur ].st = ++TimeFlag;
addr[ TimeFlag ] = weight[ cur ];
for ( int i = head[cur]; i != -; i = D[i].next )
DFS( D[i].v );
tree[cur].ed = TimeFlag;
return;
} int lowbit( int x )
{
return (-x) & x;
} void add( int x, int val )
{
while ( x <= N )
{
C[x] += val;
x += lowbit(x);
}
return;
} int query( int x )
{
int res = ;
while ( x > )
{
res += C[x];
x -= lowbit(x);
}
return res;
} bool cmp( int a, int b )
{
return weight[a] < weight[b];
} void init() //将weight离散化
{
sort( addr + , addr + N + , cmp ); int cnt = , pre = -;
for ( int i = ; i <= N; ++i )
{
if ( weight[ addr[i] ] != pre )
pre = weight[ addr[i] ], weight[ addr[i] ] = ++cnt;
else weight[ addr[i] ] = cnt;
}
return;
} bool cmp2( Queryy a, Queryy b )
{
return a.ed < b.ed;
} void solved()
{
for ( int i = ; i <= N; ++i ) pos[i].clear(); sort( qry, qry + Q, cmp2 );
int cur = ;
for ( int i = ; i <= N; ++i )
{
int val = addr[i];
pos[val].push_back(i);
int sz = pos[val].size();
if ( sz == K )
add( pos[val][ sz - K ], );
else if ( sz > K )
{
add( pos[val][ sz - K ], );
add( pos[val][ sz - K - ], - );
}
//printf( "ed = %d\n", qry[cur].ed );
while ( cur < Q && qry[cur].ed == i )
{
int id = qry[cur].i;
ans[id] = query( qry[cur].ed ) - query( qry[cur].st - );
// printf("ans[%d] = %d\n", id, ans[id] );
++cur;
}
}
return;
} int main()
{
int T, cas = ;
scanf( "%d", &T );
while ( T-- )
{
memset( head, -, sizeof( head ) );
memset( C, , sizeof(C) ); scanf( "%d%d", &N, &K );
for ( int i = ; i <= N; ++i )
{
scanf( "%d", &weight[i] );
addr[i] = i;
}
init(); EdgeN = ; for ( int i = ; i < N; ++i ) //建树
{
int u, v;
scanf( "%d%d", &u, &v );
AddEdge( u, v );
} TimeFlag = ;
DFS(); //树形结构转线性结构 scanf( "%d", &Q );
printf( "Case #%d:\n", ++cas );
for ( int i = ; i < Q; ++i )
{
int u;
scanf( "%d", &u );
qry[i].i = i;
qry[i].st = tree[u].st;
qry[i].ed = tree[u].ed;
// printf( "%d %d\n", qry[i].st, qry[i].ed );
}
solved();
for ( int i = ; i < Q; ++i )
printf( "%d\n", ans[i] ); if ( T ) puts("");
}
return ;
}
HDU 4358 Boring counting 树状数组+思路的更多相关文章
- HDU 4638 Group 树状数组 + 思路
实际上就是问这个区间编号连续的段的个数,假如一个编号连续的段有(a+b)个人,我把他们分在同一组能得到的分值为(a+b)^2,而把他们分成人数为a和b的两组的话,得到的分值就是a^2+b^2,显然(a ...
- HDU 4325 Flowers(树状数组+离散化)
http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...
- HDU - 1541 Stars 【树状数组】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1541 题意 求每个等级的星星有多少个 当前这个星星的左下角 有多少个 星星 它的等级就是多少 和它同一 ...
- HDU 3333 | Codeforces 703D 树状数组、离散化
HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...
- HDU 3854 Glorious Array(树状数组)
题意:给一些结点,每个结点是黑色或白色,并有一个权值.定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大.给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前 ...
- hdu 4217 Data Structure? 树状数组求第K小
Data Structure? Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)
题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
- hdu 1541 Stars(树状数组)
题意:求坐标0到x间的点的个数 思路:树状数组,主要是转化,根据题意的输入顺序,保证了等级的升序,可以直接求出和即当前等级的点的个数,然后在把这个点加入即可. 注意:树状数组下标从1开始(下标为0的话 ...
- HDU 3333 Turing Tree (树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意就是询问区间不同数字的和. 比较经典的树状数组应用. //#pragma comment(l ...
随机推荐
- java基础之java基本数据类型
1.Java数据类型基本概念: 数据类型在计算机语言里面,是对内存位置的一个抽象表达方式,可以理解为针对内存的一种抽象的表达方式.接触每种语言的时候,都会存在数据类型的认识,有复杂的.简单的,各种数据 ...
- mysql学习笔记之基础篇
数据库学习之基础篇 ① 开放数据库互连(Open Database Connectivity,ODBC ② 结构化查询语言(Structured Query Language) ③ 进入mysql:M ...
- 敏捷开发之道(三)极限编程XP续
上次的博文敏捷开发之道(二)极限编程XP中,我们了解了XP的实践中的其中四个,今天我们来一起学习一下剩余的实践. --接上文 5).结对编程 结对编程就是由结对的开发人员使用同一台电脑共同完成一项任务 ...
- get的四种请求形式
$_GET变量当用户以get方式请求页面并发送数据的时候,$_GET变量就存储了这些数据——get数据!get请求有4种形式:形式1:<form action=”abc.php” meth ...
- html+css学习笔记 4[定位]
如何让图1中的div2移动到如图2上的位置: 思路:哪些css命令能够影响盒子显示的位置呢? relative相对定位/定位偏移量 position:relative; 相对定位 a ...
- NYOJ-36 最长公共子序列 AC 分类: NYOJ 2014-01-03 20:54 155人阅读 评论(0) 收藏
#include<stdio.h> #include<string.h> #define N 1010 #define max(x,y) x>y?x:y int dp() ...
- [设计模式] 13 责任链模式 Chain of Responsibility
转 http://blog.csdn.net/wuzhekai1985 http://www.jellythink.com/archives/878 向项目经理提交了休假申请,我的项目经理向 ...
- unity3d android互调
unityPlayer = new AndroidJavaClass("com.xxx.xxx.MainActivity"); curActivity = unityPlayer. ...
- 因SELinux引起的用户登录问题解决案例
增强安全性带来的负作用往往是牺牲便利性,就像北京地铁的安检一样,但有些时候我们确实需要它. 案例是,用户有一台安装了KylinOS(国产麒麟,使用的是redhat的内核)的系统,当我们对其系统文件 ...
- sql中时间的比较方法
--------------------------------------------------------------------1. 当前系统日期.时间select getdate() 2. ...