Description

zzsyz实验楼里面种了一棵滑稽树,只有滑稽之力达到大乘期的oier才能看到。虽然我们看不到,但是还是知道一些信息:
这真的是一棵树,由n个节点,n-1条边联通。一号滑稽果同时也是整棵滑稽树的树根。滑稽树上每个节点有一个滑稽果,每个滑稽果有它的重量。
雪甜甜公主是神犇当然看得到那棵滑稽树啦,现在她感兴趣的是这样三件事
1:滑稽树太大啦,雪甜甜公主有的时候只想知道,在以某一个滑稽果为根的子滑稽树里面,重量第k小的果子的重量是多少?
2:除了重量第k小的果子,雪甜甜还想知道以某个滑稽果为根的子滑稽树里面,重量在[a, b]这个范围内的滑稽果有多少个。
3:雪甜甜还喜欢吃滑稽果,但是吃完,原来滑稽果的位置上还会长出一个新的滑稽果,只是重量可能不一样。

Input

第一行一个正整数n,表示滑稽树有n个节点。
第二行n个正整数,分别描述1号,2号,,,,n号节点滑稽果的重量。
接下来n-1行,每行2个正整数u, v ∈ [1, n],表示滑稽果u与滑稽果v之间有树枝连接。
接下来一个正整数q,表示雪甜甜有q次行动
之后q行,有这样3种形式
1 u k 雪甜甜公主询问以u为根的子滑稽树中,重量第k小的滑稽果的重量。
2 u a b 雪甜甜公主想知道,以u为根的子滑稽树中,重量在[a, b]范围内的滑稽果有多少个。
3 u x 雪甜甜公主吃掉了编号为u的滑稽果,但是在原位置上立刻长出来了一个重量为x的滑稽果。因为位置没有变,所以编号还是u。

Output

对于每次询问,输出结果。

Sample Input

5
3 4 6 1 2
1 2
1 3
3 4
3 5
7
1 1 4
2 1 1 5
3 4 5
1 1 4
2 3 3 6
3 5 7
1 3 3

Sample Output

4
4
5
2
7

Hint

样例提示:

数据的范围及提示:
N:
对于前35%的数据满足,N <= 5000
对于前50%的数据满足,N <= 10000
对于前100%的数据满足,N <= 30000
滑稽果的重量:对于100%d的数据满足 滑稽果的重量 <= 10000
询问:询问的个数Q:
对于前50%的数据满足 Q <= 10000
对于前100%的数据满足 Q <= 50000
对于前25%的数据,只有第一种询问。
对于前65%的数据,有第1,2种询问。
对于100%的数据第1,2,3种询问都存在。
对于前35%的数据,满足一个特殊的限制条件:每次询问的滑稽果u = 1保证询问k小重量的滑稽果的时候,k值∈ [1, 子树的节点数]

题解:

变样的整体二分,直接记录进出子树的时间戳就可以转化为区间问题,

值得注意的是查找[L,R]的个数 的地方很细节.

只有t[i].k>mid 时才可以统计,不能取等,不然就会被加入到q1 然后被重复统计

 #include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=,M=,Q=M*+N;
const int INF=-2e8;
int head[N],num=;
struct Lin{
int next,to;
}b[N<<];
void init(int x,int y){
b[++num].next=head[x];
b[num].to=y;
head[x]=num;
}
int gi(){
int str=;char ch=getchar();
while(ch>'' || ch<'')ch=getchar();
while(ch>='' && ch<='')str=(str<<)+(str<<)+ch-,ch=getchar();
return str;
}
int n,m,val[N];
struct node{
int ki,x,y,k,cnt,id;
}t[Q<<],q1[Q<<],q2[Q<<];
int dfn[N],last[N],dfns=,tot=;
void dfs(int x){
dfn[x]=++dfns;
for(int i=head[x];i;i=b[i].next){
if(!dfn[b[i].to])dfs(b[i].to);
}
last[x]=dfns;
}
int a[N],ans[M],Tree[N*];
void add(int sta,int ad){
for(int i=sta;i<=n;i+=(i&(-i)))Tree[i]+=ad;
}
int getsum(int sta){
int sum=;
for(int i=sta;i>=;i-=(i&(-i)))sum+=Tree[i];
return sum;
}
int l1,l2;
void count(int ll,int rr,int dl,int dr)
{
l1=l2=;
for(int i=ll;i<=rr;i++)
{
if(t[i].ki==)
{
t[i].cnt=getsum(t[i].y)-getsum(t[i].x-);
if(t[i].cnt>=t[i].k)q1[++l1]=t[i];
else t[i].k-=t[i].cnt,q2[++l2]=t[i];
}
else if(t[i].ki==)
{
if(t[i].k>dr)
ans[t[i].id]+=(getsum(t[i].y)-getsum(t[i].x-))*t[i].cnt,q2[++l2]=t[i];
else
q1[++l1]=t[i];
}
else
{
if(t[i].y<=dr)add(t[i].x,t[i].cnt),q1[++l1]=t[i];
else q2[++l2]=t[i];
}
}
for(int i=;i<=l1;i++)
if(q1[i].ki==)
add(q1[i].x,-q1[i].cnt);
int now=ll-;
for(int i=;i<=l1;i++)
t[++now]=q1[i];
for(int i=;i<=l2;i++)
t[++now]=q2[i];
}
void div(int ll,int rr,int dl,int dr)
{
if(dl==dr){
for(int i=ll;i<=rr;i++)
if(t[i].ki==)ans[t[i].id]=dl;
return ;
}
int mid=(dl+dr)>>;
count(ll,rr,dl,mid);
int p=l1;
if(p)
div(ll,ll+p-,dl,mid);
if(p<=rr-ll)
div(ll+p,rr,mid+,dr);
}
int main()
{
n=gi();
for(int i=;i<=n;i++)
val[i]=gi();
int x,y;
for(int i=;i<n;i++){
x=gi();y=gi();
init(x,y);init(y,x);
}
dfs();
for(int i=;i<=n;i++){
a[dfn[i]]=val[i];
t[++tot]=(node){,dfn[i],val[i],,,};
}
m=gi();
int flag,z,qnum=;
for(int i=;i<=m;i++)
{
flag=gi();
if(flag==){
x=gi();y=gi();
t[++tot]=(node){,dfn[x],last[x],y,,++qnum};
}
else
if(flag==){
x=gi();y=gi();z=gi();
t[++tot]=(node){,dfn[x],last[x],y,-,++qnum};
t[++tot]=(node){,dfn[x],last[x],z+,,qnum};
}
else{
x=gi();y=gi();
t[++tot]=(node){,dfn[x],a[dfn[x]],,-,};
t[++tot]=(node){,dfn[x],y,,,};
a[dfn[x]]=y;
}
}
div(,tot,,);
for(int i=;i<=qnum;i++)printf("%d\n",ans[i]);
return ;
}

【SYZOI Round1】滑稽的树的更多相关文章

  1. [CJOJ2425][SYZOI Round1]滑稽的树

    cjoj sol 子树转化成dfs序上的区间. 所以就变成了:区间Kth,区间内[a,b]范围内的数有多少个,单点修改 裸的树套树啊. code #include<cstdio> #inc ...

  2. [SYZOI Round1] 滑稽♂树

    题面 传送门 Sol 我也不知道哪里来的题目哪里来的\(OJ\) 子树变成\(DFS\)序后就是裸的树套树 # include <bits/stdc++.h> # define RG re ...

  3. NOI前训练日记

    向别人学习一波,记点流水帐.17.5.29开坑. 5.29 早晨看了道据说是树状数组优化DP的题(hdu5542),然后脑补了一个复杂度500^3的meet in the middle.然后死T... ...

  4. HDU 5687 Problem C

    Problem C Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  5. 【SYZOJ279】滑稽♂树(树套树)

    [SYZOJ279]滑稽♂树(树套树) 题面 SYZOJ CJOJ 题目描述 zzsyz实验楼里面种了一棵滑稽树,只有滑稽之力达到大乘期的oier才能看到.虽然我们看不到,但是还是知道一些信息: 这真 ...

  6. 搜索(四分树):BZOJ 4513 [SDOI2016 Round1] 储能表

    4513: [Sdoi2016]储能表 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 395  Solved: 213[Submit][Status] ...

  7. BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)

    我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...

  8. 【ZJOI2017 Round1练习&BZOJ4765】D1T3 普通计算姬(主席树,分块)

    题意: 思路:分块 使用树状数组维护sum[i]的前缀和 使用主席树维护root到u的路径上点的编号出现的个数 每次操作如果是修改就加入队列 如果是询问,考虑块内操作对询问的影响,每次在x点加上y会使 ...

  9. 19牛客暑期多校 round1 A 有关笛卡尔树的结论

    题目传送门//res tp nowcoder 分析 定理:B1~B2当且仅当B1与B2有同构的笛卡尔树. (B₁~B₂ iff B₁ and B₂ have isomorphic Cartesian ...

随机推荐

  1. verilog学习笔记(2)_一个小module及其tb

    module-ex_cnt module ex_cnt( input wire sclk, input wire rst_n, output wire[9:0] cnt ); reg [9:0] cn ...

  2. java中<> 的用法

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引 ...

  3. const volatile同时限定一个类型int a = 10

    const和volatile放在一起的意义在于: (1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心: (2)另一个程序段则完全有可能修改,因此编译器最好 ...

  4. android 框架LoonAndroid,码农偷懒专用

    介绍 http://www.eoeandroid.com/thread-324764-1-1.html 架构培训视频: http://pan.baidu.com/s/1mgv8HTm 简介:下载 ht ...

  5. nyoj 苹果

    苹果 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 ctest有n个苹果,要将它放入容量为v的背包.给出第i个苹果的大小和价钱,求出能放入背包的苹果的总价钱最大值. ...

  6. 微信开发之SVN提交代码与FTP同步到apache的根目录

    SVN是协同开发的,版本控制器,就是几个人同时开发,可以提交代码到SVN服务器,这样就可以协同开发,一般是早上上班首先更新下代码,然后自己修改代码 工作一天之后,修改代码之后,下班之前,更新代码,然后 ...

  7. Python机器学习—导入各种数据的N种办法

    pandas 读取数据 一.导入一般的文件 1.read_csv(),用来读取CSV文件 官方文档是这么说的:Read CSV (comma-separated) file into DataFram ...

  8. Let's Encrypt,站点加密之旅

    HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即HTTP下加入 ...

  9. LXC学习实践(3)快速体验第一个容器

    1.搭建第一个 LXC 虚拟计算机 #yum install lxc* 2.安装软件包后要检查 Linux 发行版的内核对 LXC 的支持情况,可以使用下面命令 #lxc-checkconfig #l ...

  10. eclipse使用git及github学习笔记

    项目托管 1.首先需要在github上建立一个远端仓库  点击Create repository后,会在github上建立相应的git仓库,并会出现如下界面: 复制https或者ssh的仓库地址,远端 ...