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. [Luogu 1160] 队列安排

    Luogu 1160 队列安排 链表H2O H2O H2O模板. 太久不写链表,忘干净了,竟调了半个晚上. 保留备用. #include <cstdio> #include <cst ...

  2. [POI2004] SZP (贪心+拓扑排序)

    [问题描述] Byteotian 中央情报局(BIA) 雇佣了许多特工. 他们每个人的工作就是监视 另一名特工. Byteasar 国王需要进行一次秘密行动,所以他要挑选尽量多的信得过的特工. 但 是 ...

  3. 9、MySQL常见的函数?

    请参考下面的博客文章: MySQL常见的函数

  4. Winform Socket通信

    Socket相关概念[端口] 在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应 ...

  5. bzoj 1188 SG函数

    首先我们可以把一个石子看成一个单独的游戏,那么我们可以发现所有位置的石子至于奇偶有关,因为某一个人操作其中的一个石子,我们可以用相同的石子做相同的操作,所以我们只需要保留下所有位置的01,那么对于每个 ...

  6. 【Mysql优化】索引覆盖

    索引覆盖 是指 如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据.这种查询速度非常快,称为”索引覆盖”,比平时的查询少一次到磁盘读数据的操作.(索引正好覆盖到查 ...

  7. Spark实现销量统计

    package com.mengyao.examples.spark.core; import java.io.Serializable; import org.apache.hadoop.io.Nu ...

  8. Linux汇编教程04:寻址方式

    这一节,我们主要来讨论寻址方式,这一点十分重要. 我们上一节有稍微提了一下,内存地址引用的通用格式: 地址或偏移(%基址寄存器, %索引寄存器, 比例因子 ) 结果地址 = 地址或偏移 + %基址寄存 ...

  9. HDU 5129 Yong Zheng's Death

    题目链接:HDU-5129 题目大意为给一堆字符串,问由任意两个字符串的前缀子串(注意断句)能组成多少种不同的字符串. 思路是先用总方案数减去重复的方案数. 考虑对于一个字符串S,如图,假设S1,S2 ...

  10. java多线程以及Android多线程

    Java 多线程 线程和进程的区别 线程和进程的本质:由CPU进行调度的并发式执行任务,多个任务被快速轮换执行,使得宏观上具有多个线程或者进程同时执行的效果. 进程:在操作系统来说,一个运行的程序或者 ...