Description

我曾在弦歌之中听过你,

檀板声碎,半出折子戏。

舞榭歌台被风吹去,

岁月深处尚有余音一缕……

Gty神(xian)犇(chong)从来不缺妹子……

他来到了一棵妹子树下,发现每个妹子有一个美丽度……

由于Gty很哲♂学,他只对美丽度大于某个值的妹子感兴趣。

他想知道某个子树中美丽度大于k的妹子个数。

某个妹子的美丽度可能发生变化……

树上可能会出现一只新的妹子……

维护一棵初始有n个节点的有根树(根节点为1),树上节点编号为1-n,每个点有一个权值wi。

支持以下操作:

0 u x 询问以u为根的子树中,严格大于x的值的个数。(u^=lastans,x^=lastans)

1 u x 把u节点的权值改成x。(u^=lastans,x^=lastans)

2 u x 添加一个编号为"当前树中节点数+1"的节点,其父节点为u,其权值为x。(u^=lastans,x^=lastans)

最开始时lastans=0。

Input

输入第一行包括一个正整数n(1<=n<=30000),代表树上的初始节点数。

接下来n-1行,每行2个整数u,v,为树上的一条无向边。

任何时刻,树上的任何权值大于等于0,且两两不同。

接下来1行,包括n个整数wi,表示初始时每个节点的权值。

接下来1行,包括1个整数m(1<=m<=30000),表示操作总数。

接下来m行,每行包括三个整数 op,u,v:

op,u,v的含义见题目描述。

保证题目涉及的所有数在int内。

Output

对每个op=0,输出一行,包括一个整数,意义见题目描述。

Sample Input

2

1 2

10 20

1

0 1 5

Sample Output

2

Solution

  • 大家多用的是树分块的方法,这里我用的归并树+定期重构。

  • 具体怎样呢?关键是我们考虑每个修改对之后询问的影响。

  • 如果没有修改(静态询问),我们对dfs序建归并树,直接区间查询即可。

  • (归并树就是一种线段树,区间内存的是这个区间权值排序后的序列,查询时在上面二分)

  • 有了修改,我们就要判断修改对询问有影响,其中修改点要在询问点的子树内。

  • 如何判断是否在子树内:倍增跳。加点时处理出其 2i2^i2i 级父亲。

  • 于是我们得到这样一个算法:我们在归并树中查询后,针对若干修改操作暴力判断影响。

  • 那我们就可以定期重构啦!

  • 如果我们在查询之前的修改不超过 m\sqrt mm​ 次时,就在归并树上查询后暴力扫描修改计算贡献;

  • 如果修改超过了 m\sqrt mm​ 次时,我们只要根据修改重建一下归并树就可以清除掉这些修改,

  • 可以发现归并树的重建不会超过 m\sqrt mm​ 次。

  • 那么我们来分析一下复杂度:(假设 n,mn,mn,m 同阶)

  • 每次扫描修改算贡献,修改最多 n\sqrt nn​ 个,每次倍增判是否在子树要 O(logn)O(log\ n)O(log n) ,复杂度为 O(nnlogn)O(n\sqrt n\ log\ n)O(nn​ log n) 。

  • 每次重建归并树要 O(nlogn)O(n\ log\ n)O(n log n) ,最多重建 O(logn)O(log\ n)O(log n) 次,故复杂度同是 O(nnlogn)O(n\sqrt n\ log\ n)O(nn​ log n) 。

  • 于是这题就解决了,总时间复杂度 O(nnlogn)O(n\sqrt n\ log\ n)O(nn​ log n) 。

  • 有一些细节要注意:

  • 由于重建归并树常数比较大,我们可以多几次修改再重建一次,比如说 5∗n5*\sqrt n5∗n​ 。

  • 还有就是打线段树询问时:find(1,1,n)find(1,1,n)find(1,1,n) ,由于加点时 nnn 会增加,但带进询问时仍然要是之前的 nnn ,不然就不对了,重构时再把 find(1,1,n)find(1,1,n)find(1,1,n) 的 nnn 改成新的。

Code

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cctype>
using namespace std;
const int N=60005;
struct data
{int op,x,y,z;
}q[N>>1];
int n,tot,num,cnt,qx,qy,qz,last,lim;
int first[N],nex[N<<1],en[N<<1];
int w[N],dfn[N],size[N],id[N],dep[N],fa[N][16];
vector<int>ss[N<<2];
inline int read()
{int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X;
}
void write(int x)
{if(x>9) write(x/10);putchar(x%10+'0');
}
inline void insert(int x,int y)
{nex[++tot]=first[x];first[x]=tot;en[tot]=y;
}
void dfs(int x)
{dfn[x]=++cnt;id[cnt]=x;size[x]=1;dep[x]=dep[fa[x][0]]+1;for(int i=first[x];i;i=nex[i])if(en[i]^fa[x][0]){fa[en[i]][0]=x;dfs(en[i]);size[x]+=size[en[i]];}
}
void make(int v,int l,int r)
{ss[v].clear();if(l==r){ss[v].push_back(w[id[l]]);return;}int mid=l+r>>1,ls=v<<1,rs=ls|1;make(ls,l,mid);make(rs,mid+1,r);int i=0,ni=ss[ls].size()-1;int j=0,nj=ss[rs].size()-1;while(i<=ni && j<=nj) ss[v].push_back(ss[ls][i]<ss[rs][j]?ss[ls][i++]:ss[rs][j++]);while(i<=ni) ss[v].push_back(ss[ls][i++]);while(j<=nj) ss[v].push_back(ss[rs][j++]);
}
int find(int v,int l,int r)
{if(qx<=l && r<=qy) return ss[v].size()-(upper_bound(ss[v].begin(),ss[v].end()--,qz)-ss[v].begin());int mid=l+r>>1,s=0;if(qx<=mid) s=find(v<<1,l,mid);if(qy>mid) s+=find(v<<1|1,mid+1,r);return s;
}
void dfs1(int x)
{size[x]=1;dfn[x]=++cnt;id[cnt]=x;for(int i=first[x];i;i=nex[i])if(en[i]^fa[x][0]){dfs(en[i]);size[x]+=size[en[i]];}
}
inline void rebuild()
{cnt=num=0;dfs1(1);make(1,1,n);cnt=n;
}
inline bool belong(int x,int y)
{if(dep[x]<dep[y]) return false;for(int i=log2(dep[x]);i>=0;i--)if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];return x==y;
}
int main()
{n=read();for(int i=1;i<n;i++){int x=read(),y=read();insert(x,y);insert(y,x);}for(int i=1;i<=n;i++) w[i]=read();dfs(1);cnt=n;for(int j=1;j<16;j++)for(int i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1];make(1,1,n);int m=read();lim=ceil(sqrt(m)*5);while(m--){int op=read(),x=read()^last,y=read()^last;if(op==0){if(x<=cnt){qx=dfn[x],qy=dfn[x]+size[x]-1,qz=y;last=find(1,1,cnt);}else last=0;for(int i=1;i<=num;i++)if(q[i].op==1){if((q[i].y<y)^(q[i].z<y) && belong(q[i].x,x)) last+=q[i].z>y?1:-1;}else{if(q[i].z>y && belong(q[i].x,x)) last++;}write(last),putchar('\n');}elseif(op==1){q[++num]=(data){1,x,w[x],y};w[x]=y;if(num==lim) rebuild();}else{q[++num]=(data){2,++n,x,y};insert(x,n);insert(n,x);fa[n][0]=x;dep[n]=dep[x]+1;w[n]=y;for(int i=1;i<16;i++) fa[n][i]=fa[fa[n][i-1]][i-1];if(num==lim) rebuild();}}return 0;
}

BZOJ 3720 [洛谷P2137] : Gty的妹子树相关推荐

  1. 块状树(bzoj 3720: Gty的妹子树)

    问题概述: 一棵n个节点的树,每个节点都有一个权值,之后三种操作: ①0 u v查询以u点为根的子树中权值大于v的有多少个 ②1 u v表示将u点的权值修改为v ③2 u v表示新建一个节点,编号为节 ...

  2. 3720: Gty的妹子树

    3720: Gty的妹子树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1440  Solved: 482 [Submit][Status][Di ...

  3. #莫比乌斯反演#BZOJ 2671 洛谷 4466 和与积 Calc

    题目 求有多少对(a,b)(a,b)(a,b)满足1≤a<b≤n1\leq a<b\leq n1≤a<b≤n且a+b∣aba+b|aba+b∣ab 分析 若gcd(a,b)=1gcd ...

  4. BZOJ 4385 洛谷3594 POI2015 WIL-Wilcze doły

    [题解] 手残写错调了好久QAQ...... 洛谷的数据似乎比较水.. n个正整数!!这很重要 这道题是个类似two pointer的思想,外加一个单调队列维护当前区间内长度为d的子序列中元素之和的最 ...

  5. BZOJ 2733 | 洛谷 P3224 [HNOI2012]永无乡

    https://www.lydsy.com/JudgeOnline/problem.php?id=2733 https://www.luogu.org/problemnew/show/P3224 C+ ...

  6. bzoj 2653 洛谷 P2839 [国家集训队] middle

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2381  Solved: 1340 [Submit][Status][Di ...

  7. #距离#JZOJ 3256 BZOJ 3170 洛谷 3964 松鼠聚会

    题目 分析 首先这个距离是切比雪夫距离,得把它转换成曼哈顿距离,也就是把(x,y)(x,y)(x,y)变成(x+y2,x−y2)(\frac{x+y}{2},\frac{x-y}{2})(2x+y​, ...

  8. #快速幂,eratosthenes筛#bzoj 3930 洛谷 3172 选数

    题目 从区间 [ l ∼ r ] [l\sim r] [l∼r]中选取 n n n个整数,总共有 ( r − l + 1 ) n (r-l+1)^n (r−l+1)n种方案.问最大公约数刚好为 k k ...

  9. bzoj 1296 洛谷4158 [SCOI2009]粉刷匠 题解

    题意简述 一个 n × m n\times m n×m的矩阵,每个位置珂能是粉色(0表示)或者是蓝色(1表示),然后你珂以对同一行里连续一段长度的区间染上一种颜色(覆盖型),你能染 t t t次,每次 ...

最新文章

  1. ui设计和python哪个容易学_软件开发和ui设计那个容易学?
  2. 康普在金色一号中心缔造光纤新历史
  3. MySql DATE_FORMAT函数用法
  4. 自定义Spring命名空间使JAXB更容易
  5. php文件的作用,php入口文件的作用-PHP问题
  6. SQL 获取指定月份的天数
  7. HDU4706 Children's Day
  8. 如何创建ChromeApp
  9. 开课吧Java教程:如何用listFiles()方法
  10. asp.net中使用下拉菜单的级联问题
  11. 关于时间格式的解析问题
  12. 计算机系最好的985大学排名,2017年全国“985”大学排名及王牌专业全解析
  13. win11微软拼音输入法失效、没有候选框、不显示语言栏的问题
  14. web前端期末大作业:婚纱网页主题网站设计——唯一旅拍婚纱公司网站HTML+CSS+JavaScript
  15. 脑科学和人工智能的思考
  16. 用Python自制随机点名程序,压迫感来了~
  17. springboot 之 SpringBoot指定额外需要扫描的包
  18. linux 转换viso为pdf,foxpdf Visio转PDF转换器
  19. java不能连接mysql_java无法连接数据库问题(急)
  20. ArcGIS将太平洋调至地图中间(改变地图中心经度)

热门文章

  1. YOLO v3解析与实现
  2. [云炬创业管理笔记]第三章测试1
  3. 云炬Android开发笔记 4单Activity界面架构设计与验证
  4. OpenGL编程指南7:视图-
  5. Javascript之浏览器对象
  6. EffectiveC++编程的50个建议
  7. HTML中a标签/超链接标签的下划线怎么去掉
  8. 十进制数转换为二进制数
  9. 从web.xml谈谈SpringMVC集成spring的初始化流程及SpringBoot集成SpringMVC
  10. java return this