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 然后被重复统计

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 #include <cmath>
  7 using namespace std;
  8 const int N=30005,M=50005,Q=M*2+N;
  9 const int INF=-2e8;
 10 int head[N],num=0;
 11 struct Lin{
 12     int next,to;
 13 }b[N<<1];
 14 void init(int x,int y){
 15     b[++num].next=head[x];
 16     b[num].to=y;
 17     head[x]=num;
 18 }
 19 int gi(){
 20     int str=0;char ch=getchar();
 21     while(ch>'9' || ch<'0')ch=getchar();
 22     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
 23     return str;
 24 }
 25 int n,m,val[N];
 26 struct node{
 27     int ki,x,y,k,cnt,id;
 28 }t[Q<<1],q1[Q<<1],q2[Q<<1];
 29 int dfn[N],last[N],dfns=0,tot=0;
 30 void dfs(int x){
 31         dfn[x]=++dfns;
 32         for(int i=head[x];i;i=b[i].next){
 33                 if(!dfn[b[i].to])dfs(b[i].to);
 34         }
 35         last[x]=dfns;
 36 }
 37 int a[N],ans[M],Tree[N*4];
 38 void add(int sta,int ad){
 39     for(int i=sta;i<=n;i+=(i&(-i)))Tree[i]+=ad;
 40 }
 41 int getsum(int sta){
 42     int sum=0;
 43     for(int i=sta;i>=1;i-=(i&(-i)))sum+=Tree[i];
 44     return sum;
 45 }
 46 int l1,l2;
 47 void count(int ll,int rr,int dl,int dr)
 48     {
 49         l1=l2=0;
 50         for(int i=ll;i<=rr;i++)
 51             {
 52                 if(t[i].ki==1)
 53                     {
 54                         t[i].cnt=getsum(t[i].y)-getsum(t[i].x-1);
 55                         if(t[i].cnt>=t[i].k)q1[++l1]=t[i];
 56                         else t[i].k-=t[i].cnt,q2[++l2]=t[i];
 57                     }
 58                 else if(t[i].ki==2)
 59                     {
 60                         if(t[i].k>dr)
 61                             ans[t[i].id]+=(getsum(t[i].y)-getsum(t[i].x-1))*t[i].cnt,q2[++l2]=t[i];
 62                         else
 63                             q1[++l1]=t[i];
 64                     }
 65                 else
 66                     {
 67                         if(t[i].y<=dr)add(t[i].x,t[i].cnt),q1[++l1]=t[i];
 68                         else q2[++l2]=t[i];
 69                     }
 70              }
 71         for(int i=1;i<=l1;i++)
 72             if(q1[i].ki==3)
 73                 add(q1[i].x,-q1[i].cnt);
 74    int now=ll-1;
 75         for(int i=1;i<=l1;i++)
 76             t[++now]=q1[i];
 77         for(int i=1;i<=l2;i++)
 78             t[++now]=q2[i];
 79     }
 80 void div(int ll,int rr,int dl,int dr)
 81     {
 82         if(dl==dr){
 83             for(int i=ll;i<=rr;i++)
 84                 if(t[i].ki==1)ans[t[i].id]=dl;
 85             return ;
 86         }
 87         int mid=(dl+dr)>>1;
 88         count(ll,rr,dl,mid);
 89         int p=l1;
 90         if(p)
 91             div(ll,ll+p-1,dl,mid);
 92         if(p<=rr-ll)
 93             div(ll+p,rr,mid+1,dr);
 94     }
 95 int main()
 96 {
 97     n=gi();
 98     for(int i=1;i<=n;i++)
 99         val[i]=gi();
100     int x,y;
101     for(int i=1;i<n;i++){
102         x=gi();y=gi();
103         init(x,y);init(y,x);
104     }
105     dfs(1);
106     for(int i=1;i<=n;i++){
107         a[dfn[i]]=val[i];
108         t[++tot]=(node){3,dfn[i],val[i],0,1,0};
109     }
110     m=gi();
111     int flag,z,qnum=0;
112     for(int i=1;i<=m;i++)
113         {
114             flag=gi();
115             if(flag==1){
116                     x=gi();y=gi();
117                     t[++tot]=(node){1,dfn[x],last[x],y,0,++qnum};
118                 }
119             else
120                 if(flag==2){
121                     x=gi();y=gi();z=gi();
122                     t[++tot]=(node){2,dfn[x],last[x],y,-1,++qnum};
123                     t[++tot]=(node){2,dfn[x],last[x],z+1,1,qnum};
124                 }
125                 else{
126                     x=gi();y=gi();
127                     t[++tot]=(node){3,dfn[x],a[dfn[x]],0,-1,0};
128                     t[++tot]=(node){3,dfn[x],y,0,1,0};
129                     a[dfn[x]]=y;
130                 }
131         }
132     div(1,tot,0,10000);
133     for(int i=1;i<=qnum;i++)printf("%d\n",ans[i]);
134     return 0;
135 }

转载于:https://www.cnblogs.com/Yuzao/p/7112895.html

【SYZOI Round1】滑稽的树相关推荐

  1. #279. [SYZOI Round1] 滑稽♂树(树状数组套主席树)

    #279. [SYZOI Round1] 滑稽♂树 子树上的问题,考虑dfsdfsdfs序,第kkk大,可以用主席树嘛,支持修改,那就树状数组上套主席树,参考P4175 [CTSC2008]网络管理( ...

  2. 主席树有关的一些题目(持续更新)

    主席树 模板 P3919 [模板]可持久化线段树 1(可持久化数组) #include <bits/stdc++.h>using namespace std;const int N = 1 ...

  3. 滑稽树下你和我Average distance(树形dp求任意两点距离之和)

    滑稽树下你和我. 链接:https://ac.nowcoder.com/acm/contest/992/J 来源:牛客网 题目描述 红红和蓝蓝是随机降生在苹果树上的苹果仙灵,现在红线仙想估测他们的CP ...

  4. D、数列求和(嘤雄难度) J、滑稽树下你和我 I、滑稽树上滑稽果

    D.数列求和(嘤雄难度) 1.  2. 3.考虑先求出  的所有质因数,然后通过容斥来求所有与  不互质的  的和. 4.假设当前容斥算的质数是  ,那么就有  个该质数的倍数,即要求 ,式子化简得, ...

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

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

  6. 滑稽树下你和我(树+贡献)

    链接:https://ac.nowcoder.com/acm/contest/992/J?&headNav=acm 来源:牛客网 题目描述 红红和蓝蓝是随机降生在苹果树上的苹果仙灵,现在红线仙 ...

  7. 吉首大学2019年程序设计竞赛(重现赛) J 滑稽树下你和我 (递归)

    链接:https://ac.nowcoder.com/acm/contest/992/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...

  8. szu 寒训个人复习第一天 线段树入门单点修改,区间修改,以及线段树的扩展运用[线段树+dp][区间最大公约数]

    寒讯内容有点过多(其实是我太菜了)水一波怕忘了(人老了)**什么是线段树** 线段树是本蒟蒻感觉用处特别大的算法 那么线段树上面的节点表示什么意思呢? 线段树,上面的节点表示一个区间,父亲节点表示的区 ...

  9. Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)

    题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...

  10. 2018.06.28 与或(线段树)

    #与或 描述 样例输入 5 8 1 3 2 5 4 3 1 3 2 1 1 5 3 1 3 1 1 4 6 2 3 4 1 3 2 3 2 2 3 4 3 1 5 **样例输出 ** 3 5 3 7 ...

最新文章

  1. Oracle Block浅析2:ITL(Interested Transaction List)
  2. Centos下安装MongoDB复制集
  3. mysql中删除同一行会经常出现死锁?太可怕了
  4. Java基础与提高干货系列——Java反射机制
  5. php创蓝253四要素认证_PHP下基于创蓝253接口的短信发送
  6. 【PAT甲级 最长公共子串】1007 Maximum Subsequence Sum (25 分) C++ 全部AC
  7. 二 SVN代码冲突的解决
  8. oracle不属于集合操作,Oracle的几个集合操作
  9. 数据科学 IPython 笔记本 7.9 组合数据集:连接和附加
  10. Dos下面删除文件秘笈
  11. 【Flask+SocketIO】如何用Flask做一个快捷迷你的局域网聊天室
  12. LPC845-BRK开发板运行Blinky示例程序
  13. 7z解压crc错误_.7z解压文件末端错误 如何解压分卷压缩包 - 电脑故障 - 服务器之家...
  14. Vmware 虚拟机设置主机映射端口
  15. 【深信服】Python 开发工程师(云计算、网络安全) 【已offer】
  16. matplotlib的cmap
  17. QString 16进制,arg补0,从0xFFFFFFFFFFFFFFFA到0xFA
  18. 剑指Offer-05:替换空格
  19. Springboot毕设项目校园二手交易平台x9zo8java+VUE+Mybatis+Maven+Mysql+sprnig)
  20. 三十三、CSS三角的做法用户界面样式

热门文章

  1. web集群之LVS集群
  2. 简洁/易用/灵活/高效-RecyclerView适配器封装
  3. webstorm的下载以及React环境搭建
  4. Unity3D场景漫游以及碰撞防止反弹
  5. Numpy 数组的切片操作
  6. JavaScript服务器端高级编程(Array.indexOf()和lastIndexOf()方法)
  7. Python中lambda的用法及其与def的区别解析
  8. 第九集(第二部分)思科路由器IOS升级过程视频记录
  9. 用python实现一个socket echo程序 tcp socket的几个关闭状态
  10. 中国未来5年IP地址需求总量高达345亿