Problem 2245 动态树

Accept: 17    Submit: 82
Time Limit: 3000 mSec    Memory Limit : 65536 KB

 Problem Description

YellowStar拥有一棵神奇的动态树,该树由n个带权结点,n-1条边构成,任意两个结点互相可达,标号为i结点的权值为Wi。

由于物质是运动的,这棵树每天都会发生一些变化,在第i天,该树权值在[l,r]的结点会发出强烈的光芒,YellowStar看到这一现象会非常的愉悦,它的愉悦值取决于:发光的这些结点构成了多少个连通子树。

现在你知道动态树在接下来m天的发光情况,请你计算出YellowStar每一天的愉悦值

 Input

第一行输入T,表示有T组样例(T <= 20)

每组样例第一行为n,表示树的结点个数(1 <= n <= 1e5)

接下来n个数字W1, W2, ... , Wn (1 <= Wi <= 1e9)表示每个结点的权值

接下来n - 1行,每一行两个数字u, v (1 <= u, v <= n)表示树边

接下来一个数字m(1 <= m <= 1e5),表示m天

接下来m个询问,每个询问一行l, r (1 <= l <= r <= 1e9)表示每一天发光的结点的权值区间

 Output

每组样例输出m行,表示YellowStar在这m天的愉悦值

 Sample Input

1
3
1 3 2
1 2
1 3
3
1 3
1 2
2 3

 Sample Output

1
1
2

 Hint

long long类型请用%I64d输出

 Source

FOJ有奖月赛-2017年4月(校赛热身赛)

【分析】给你一棵树,每个节点有一个权值([1,1e9]),然后Q次询问,每次给出一个区间[l,r],问权值处在这个区间内的节点构成的联通块有多少个。
 一开始想到的是并查集+莫队,后来发现并查集那边不好处理。听了学长的,先将所有权值离散,区间离线,按照右端点从小到大排序。然后对于,每一条边,也看成一个区间
跟前面一样排序。然后,对于一次查询区间,这个区间里有多少点这个我们是可以预处理出来的,假设是S个,也就是没有边的时候联通块是S个,若其中有两个点连有一条边,
那么联通块-1,有多少边,S就减多少。现在的问题转化成了查询区间内有多少边。由于我们是排了序的,所以我们固定查询的右端点,对于右端点<=查询右端点的边,用树状数组
统计<=右端点的边有多少就行了。
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <map>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int>pii;
const int N = 1e5+;
const double eps = 1e-;
int T,n,w[N],sum[N<<],p[N<<],cnt,m,ret[N],c[N<<];
struct Query{
int l,r,id;
bool operator<(const Query &rhs)const{
return r<rhs.r;
}
}q[N],t[N];
void add(int x){
for(;x<=cnt;x+=x&-x)++c[x];
}
int ask(int x){
int ret = ;
for(;x>;x-=x&-x)ret+=c[x];
return ret;
}
int main() {
scanf("%d",&T);
while(T--){
scanf("%d",&n);
cnt = ;
for(int i=;i<=n;++i){
scanf("%d",&w[i]);
p[++cnt]=w[i];
}
for(int i=;i<n;++i){
scanf("%d%d",&t[i].l,&t[i].r);
t[i].l=w[t[i].l];
t[i].r=w[t[i].r];
}
scanf("%d",&m);
for(int i=;i<=m;++i){
scanf("%d%d",&q[i].l,&q[i].r);
p[++cnt]=q[i].l;
p[++cnt]=q[i].r;
q[i].id=i;
}
sort(p+,p++cnt);
cnt=unique(p+,p++cnt)-p-;
for(int i=;i<=cnt;++i)c[i]=sum[i]=;
for(int i=;i<=n;++i){
w[i]=lower_bound(p+,p++cnt,w[i])-p;
++sum[w[i]];
}
for(int i=;i<=cnt;++i)sum[i]+=sum[i-];
for(int i=;i<n;++i){
t[i].l=lower_bound(p+,p++cnt,t[i].l)-p;
t[i].r=lower_bound(p+,p++cnt,t[i].r)-p;
if(t[i].l>t[i].r)swap(t[i].l,t[i].r);
}
for(int i=;i<=m;++i){
q[i].l=lower_bound(p+,p++cnt,q[i].l)-p;
q[i].r=lower_bound(p+,p++cnt,q[i].r)-p;
}
if(n!=)sort(t+,t++n-);
sort(q+,q++m);
int j=;
for(int i=;i<=m;++i){
ret[q[i].id]=sum[q[i].r]-sum[q[i].l-];
for(;j<=n-&&t[j].r<=q[i].r;++j)add(t[j].l);
ret[q[i].id]-=ask(q[i].r)-ask(q[i].l-);
}
for(int i=;i<=m;++i)printf("%d\n",ret[i]);
}
return ;
}
 

FZOJ 2245 动态树(离散+离线+ 树状数组)的更多相关文章

  1. 【BZOJ2434-[Noi2011]】阿狸的打字机(AC自动机(fail树)+离线+树状数组)

    Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的 ...

  2. HDU 5869 Different GCD Subarray Query rmq+离线+数状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5869 Different GCD Subarray Query Time Limit: 6000/3 ...

  3. HDU 3333-Turing Tree-线段树+离散+离线

    Description After inventing Turing Tree, 3xian always felt boring when solving problems about interv ...

  4. SPOJ DQUERY - D-query (莫队算法|主席树|离线树状数组)

    DQUERY - D-query Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query ...

  5. [bzoj3155]Preprefix sum(树状数组)

    3155: Preprefix sum Time Limit: 1 Sec  Memory Limit: 512 MBSubmit: 1183  Solved: 546[Submit][Status] ...

  6. Codeforces 980E The Number Games - 贪心 - 树状数组

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一颗有$n$个点的树,$i$号点的权值是$2^{i}$要求删去$k$个点,使得剩下的点仍然连通,并且总权值和最大,问删去的所有点的编号. ...

  7. Gym 100342F Move to Front (树状数组动态维护和查询)

    用树状数组动态和查询修改排名. 树状数组可以很方便地查询前缀和,那么可以利用这一特点,记录一个点在树状数组里最后一次出现的位置, 查询出这个位置,就可以知道这个点的排名了.更改这个点的排名的时候只要把 ...

  8. 2016 大连网赛---Different GCD Subarray Query(GCD离散+树状数组)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5869 Problem Description This is a simple probl ...

  9. POJ 3416 Crossing --离线+树状数组

    题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...

随机推荐

  1. 洛谷P2901 [USACO08MAR]牛慢跑Cow Jogging

    题目描述 Bessie has taken heed of the evils of sloth and has decided to get fit by jogging from the barn ...

  2. .NET中方法的注意事项 明细

    1. 方法中return 会终止整个方法段. 而break只能终止当前循环. 2. 方法就是一对可用代码的复用. a . 对于可重用的代码,在vs中选中,右键  重构  提取方法.即可自动封装成一个方 ...

  3. 你自认为理解了JavaScript?【转】

    第一题 if (!("a" in window)) { var a = 1; } alert(a); 第二题 var a = 1, b = function a(x) { x &a ...

  4. Html5_sessionStrong和localStorage的灵活使用

    谈谈这两个属性sessionStrong和localStorage是Html5新增点属性,用来记录一些数据在浏览器. 两者的区别sessionStrong存储的数据是暂时的,浏览器关掉后,存储下来的数 ...

  5. Ribbon自带负载均衡策略比较

    Ribbon自带负载均衡策略比较 策略名 策略声明 策略描述 实现说明 BestAvailableRule public class BestAvailableRule extends ClientC ...

  6. Linux 入门记录:十三、Linux 扩展权限

    一.默认权限 每一个终端都有一个 umask 属性,是用来确定新建文件或目录的默认权限的“掩码”(mask 有“掩码”的含义,至于 u,后面说). Linux 中一般有默认的权限掩码,使用命令 uma ...

  7. HDU 5136 Yue Fei's Battle

    题目链接:HDU-5136 网上的一篇题解非常好,所以就直接转载了.转自oilover的博客 代码: #include<cstring> #include<cstdio> #i ...

  8. caffe Python API 之激活函数ReLU

    import sys import os sys.path.append("/projects/caffe-ssd/python") import caffe net = caff ...

  9. leetcode 之Gas Station(11)

    这题的思路很巧妙,用两个变量,一个变量衡量当前指针是否有效,一个衡量整个数组是否有解,需要好好体会. int gasStation(vector<int> &gas, vector ...

  10. HDU 3669 Cross the Wall(斜率DP+预处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3669 题目大意:有n(n<=50000)个矩形,每个矩形都有高和宽,你可以在墙上最多挖k个洞使得 ...