CF1137F Matches Are Not a Child‘s Play(树上数据结构问题、树链剖分+ODT)

Description

一棵 n 个点的树,点权最初为 1 ∼ n 的排列。
定义一个删点过程:每次找到权值最小的叶子,删去它以及连接的边,重复这个过程直到剩下一个点,然后删去最后的点。
处理 q 个询问:

  • 将一个点 x 的权值赋为当前最大权值 +1。
  • 查询在删点过程中,x 会是第几个被删除的。
    n, q ≤ 2×1052 \times 10^52×105

Solution

  • 观察到删除序列的一些性质:
  1. 权值最大的点最后一个被删。
  2. 权值最大的点为 x,次大的为 y,那么序列最后一段就是 y 到 x 的简单路径。
  • 不难分析,一次赋值操作,不会影响非 y → x 路径上的点的变叶子过程,所以造成的影响就是将 y → x 路径提到序列最后,其他点的顺序不变。(设给y赋值,x为原权值最大的点)
  • 所以,不妨先把初始序列模拟出来,然后维护它。
  • 转化一下模型:修改权值变为将 y → x 的路径染上一种新的颜色。
  • 那么询问 z 就变成了;多少点的颜色出现早于 z 颜色,以及与 z 同色的点优先于 z 的个数。
  • 维护颜色/同色的优先级可以用树链剖分 + 线段树 或 树链剖分 + ODT,每种颜色的点数可以直接树状数组。
  • 具体讲ODT做法:先树剖,对于每一条重链,维护一个set,set里维护这条重链上的颜色区间。那么一次区间覆盖只要把旧的区间删去,并加入新的区间就行了。

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<set>
using namespace std;
const int N=200035;
const int M=400035;
struct Edge{int v,nxt;
}edge[M];
int n,q,cnt,head[N],tim,root[N*2];
int deg[N],fa[N],dep[N],siz[N],son[N],top[N],dfn[N],ind;
char opt[20];
struct node{//ODTint l,r,val;node(int a=0,int b=0,int c=0):l(a),r(b),val(c) {}bool operator < (node b) const {return l<b.l;}
};
set<node> s[N];
typedef set<node>::iterator itr; 
priority_queue<int,vector<int>,greater<int> > que;
namespace BIT{int c[N*2];void add(int i,int x){for(i+=5;i<=n+q+5;i+=i&-i) c[i]+=x;}int sum(int i){int res=0;for(i+=5;i;i-=i&-i) res+=c[i];return res;}
};
void add(int u,int v){edge[++cnt].v=v;edge[cnt].nxt=head[u];head[u]=cnt;
}
void dfs1(int u,int f){fa[u]=f;dep[u]=dep[f]+1;top[u]=son[u]=-1;siz[u]=1;for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].v;if(v==f) continue;dfs1(v,u);siz[u]+=siz[v];if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v;}
}
void dfs2(int u,int tp){if(u==tp){s[u].insert(node(n+1,n+1,0));}dfn[u]=++ind;top[u]=tp;if(son[u]==-1) return;dfs2(son[u],tp);for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].v;if(v!=fa[u]&&v!=son[u]) dfs2(v,v);}
}
itr split(int i,int pos){itr loc=s[i].lower_bound(node(pos));if(loc!=s[i].end()&&loc->l==pos) return loc;int l=(--loc)->l,r=loc->r,val=loc->val;s[i].erase(loc);s[i].insert(node(l,pos-1,val));return s[i].insert(node(pos,r,val)).first;
}
void insert(int i,int l,int r,int c){itr rpos=split(i,r+1),lpos=split(i,l);for (itr it=lpos;it!=rpos;++it)BIT::add(it->val,-(it->r-it->l+1));//遍历清除历史颜色s[i].erase(lpos,rpos);BIT::add(c,r-l+1);s[i].insert(node(l,r,c));
}
int LCA(int u,int v){while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) v=fa[top[v]];else u=fa[top[u]];}if(dep[u]<dep[v]) return u;return v;
}
int dist(int u,int v){int lca=LCA(u,v);return dep[u]+dep[v]-(dep[lca]<<1);
}
void ChainModify(int u,int v){while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);insert(top[u],dfn[top[u]],dfn[u],tim);u=fa[top[u]];}if(dep[u]<dep[v]) swap(u,v);insert(top[v],dfn[v],dfn[u],tim);
}
int query(int u){int c=split(top[u],dfn[u])->val;return BIT::sum(c-1)+dist(u,root[c-1])+1;//root[c-1]是指上一个历史版本节点编号最大的一个元素
}
int main(){scanf("%d%d",&n,&q);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);add(x,y);add(y,x);deg[x]++;deg[y]++;}dfs1(1,0);dfs2(1,1);//先搞出初始序列: for(int i=1;i<=n;i++) if(deg[i]==1) que.push(i);for(int i=1;i<=n;i++){int u=que.top();que.pop();root[i-1]=root[i]=u;//写成root[i-1]=root[i]=u是因为对于初始序列,查询时候要保持dist(u,root[c-1])=0;但是对于之后修改的询问root[n]应该为nBIT::add(i,1);deg[u]=0;s[top[u]].insert(node(dfn[u],dfn[u],++tim));//node不加括号啊啊啊,为这个调了我一天 for(int i=head[u];i;i=edge[i].nxt)if((--deg[edge[i].v])==1) que.push(edge[i].v); }//不断修改、查询序列: for(int i=1;i<=q;i++){//用while(q--)就错?why? int u,v;scanf("%s",opt);if(opt[0]=='u'){scanf("%d",&u);root[++tim]=u;ChainModify(u,root[tim-1]);}else if(opt[0]=='w'){scanf("%d",&u);printf("%d\n",query(u));}else{scanf("%d%d",&u,&v);printf("%d\n",(query(u)<query(v))?u:v);}}return 0;
}

参考文章:
https://www.cnblogs.com/bztMinamoto/p/10537308.html
https://www.cnblogs.com/antiquality/p/10660122.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小石的签到题

链接&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 输入描述: 共一行&#xff0c;输入一个数 n 。 输出描述: 共一行&#xff0c;输出 “Shi” 或 “Yang”&…

值类型、引用类型和泛型的前世今生

值类型、引用类型和泛型多语言咱们先不说主题&#xff0c;先说说CLR支持多语言。 .net有个非常强大的特点&#xff0c;那就是跨语言&#xff0c;支持很多语言&#xff0c;比如C#、J#等。先来个图看一看C# J# VB 等等等

P3247-[HNOI2016]最小公倍数【分块,并查集】

正题 题目链接:https://www.luogu.com.cn/problem/P3247 题目大意 nnn个点mmm条边&#xff0c;每条边有(x,y,a,b)(x,y,a,b)(x,y,a,b)。qqq次询问(x′,y′,a′,b′)(x,y,a,b)(x′,y′,a′,b′)表示询问是否存在一条x′−>y′x->yx′−>y′的路径使得路径上amaxa′,bma…

【DP】奖励卡(jzoj 3937)

奖励卡 jzoj 3937 题目大意 现在有一场比赛&#xff0c;想观看的人要提交申请&#xff0c;现在有x个人提交后得到两个号&#xff0c;y个人提交后得到一个号&#xff0c;有n轮抽号&#xff0c;每一轮抽一个号&#xff08;概率相等&#xff09;&#xff0c;这个号的所有者不参…

CF526G Spiders Evil Plan(树上最优性问题、倍增+线段树)

Description 一棵 n 个结点的树&#xff0c;有正边权。 用 y 条链覆盖这棵树&#xff0c;满足&#xff1a; 所有链连通&#xff08;有重点即算作相连&#xff09;点 x 被覆盖被覆盖的边的权值和尽可能大 q 次给出 x, y&#xff0c;询问最大边权和&#xff0c;强制在线。 n, q…

CAP带你轻松玩转ASP.NETCore消息队列

CAP是什么&#xff1f;CAP是由我们园子里的杨晓东大神开发出来的一套分布式事务的决绝方案&#xff0c;是.Net Core Community中的第一个千星项目&#xff08;目前已经1656 Start&#xff09;&#xff0c;具有轻量级、易使用、高性能等特点。https://github.com/dotnetcore/CAP…

装备合成

链接&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 输入描述: 输入包含t组数据 第一行一个整数t 接下来t行每行两个整数x,y 输出描述: 每组数据输出一行一个…

P4161-[SCOI2009]游戏【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P4161 题目大意 一个1∼n1\sim n1∼n的排列&#xff0c;f(x)f(x)f(x)表示在置换xxx下置换多少次才能回到原来的排列&#xff0c;求在所有置换下f(x)f(x)f(x)的所有可能的值的数量。 解题思路 一个置换的fff值就是这个置换的…

【spfa】假期计划(jzoj 3936)

假期计划 jzoj 3936 题目大意 给你一个有向图&#xff08;n,m⩽20000n,m\leqslant 20000n,m⩽20000&#xff09;&#xff0c;现在有一些作为枢纽的点&#xff0c;且保证每一条边的两个点至少有一个是枢纽点&#xff0c;现在给q个询问&#xff0c;问某一个点到另一个点的最短…

CF650E Clockwork Bomb(树上构造类问题、并查集)

Description 给出两棵 n 结点的有标号树。 每次操作删去第一棵树的一条边&#xff0c;再加上一条边&#xff0c;需要保证此时还是一棵树。 构造一种操作序列&#xff0c;将第一棵树变成第二棵树&#xff0c;使得操作数最小。 n ≤ 51055 \times 10^55105 Solution 显然&…

微软必应从.NET Core 2.1获得了性能提升

据微软工程师Mukul Sabharwal介绍&#xff0c;在将微软搜索引擎必应迁移到.NET Core 2.1之后&#xff0c;内部服务延迟降低了34%&#xff0c;这主要归功于.NET社区贡献的改进。按照Sabharwal的说法&#xff0c;.NET Core的多项改进贡献了大部分的性能提升&#xff0c;包括字符串…

阶乘

链接&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 给定一个正整数 p 求一个最小的正整数 n&#xff0c;使得 n! 是 p 的倍数 输入描述: 第一行输入一个正整数…

P2151-[SDOI2009]HH去散步【矩阵乘法】

正题 题目链接:https://www.luogu.com.cn/problem/P2151 题目大意 nnn个点mmm条边的一张无向图&#xff0c;走过一条边后下一次就不能再走这条&#xff0c;求AAA到BBB之间有多少长度为ttt的路径。 解题思路 因为有不能再走同一条的限制&#xff0c;所以不能直接裸上矩乘&…

IQ测试(jzoj 5048)

IQ测试 jzoj 5048 题目大意 给出一个序列a&#xff0c;然后有m个询问&#xff0c;每个询问给出一个序列&#xff0c;问这个序列是否可以由序列a删掉一些数得到的 输入样例 7 1 5 4 5 7 8 6 4 5 1 5 5 8 6 3 2 2 2 3 5 7 8 4 1 5 7 4输出样例 TAK NIE TAK NIE数据范围 对…

CF1088F Ehab and a weird weight formula(树上最优性问题、贪心+倍增)

Description 给出一棵 n 个结点的树&#xff0c;点 i 有正权值 wiw_iwi​&#xff0c;wiw_iwi​ 互不相同。 除了权值最小的点&#xff0c;保证每个点 u 都有一个邻点 v 使得 wvw_vwv​ < wuw_uwu​。 构造一棵树&#xff0c;最小化代价&#xff1a; 对于每个点 u&#xf…

搭建基于云端的中间层以支持跨平台的智能视觉服务

不断演进的应用场景初级应用场景—宅在家里场景&#xff1a;Bob同学有一天在网上看到了一张建筑物的图片&#xff0c;大发感慨&#xff1a;"好漂亮啊&#xff01;这是哪里&#xff1f;我要去亲眼看看&#xff01;"Bob同学不想问别人&#xff0c;可笑的自尊心让他觉得…

YbtOJ#20235-[冲刺NOIP2020模拟赛Day9]公共序列【dp】

正题 题目链接:https://www.ybtoj.com.cn/contest/66/problem/3 题目大意 给出两个字符串A,BA,BA,B&#xff0c;求它们的最长公共子序列。 解题思路 先考虑朴素的dpdpdp&#xff0c;设fi,jf_{i,j}fi,j​表示到AAA的第iii个&#xff0c;BBB的第jjj个时候的最长公共子序列长度…

牛客算法周周练4 题解

比赛链接 文章目录A [SDOI2016]齿轮B Rinne Loves XorC 阶乘D 小石的签到题E 装备合成A [SDOI2016]齿轮 B Rinne Loves Xor C 阶乘 两个方法 题解 D 小石的签到题 题解 E 装备合成 两个方法 题解

纪中B组模拟赛总结(2020.2.22)

成绩 rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3333lyflyflyf160160160100100100101010505050 总结 T1想到DP&#xff0c;但一开始想到的方法会TLE&#xff0c;后来想到可以减去一层&#xff0c;就A了 T2瞎想了一波&#xff0c;打了一个类似于FloyedFloyedFl…

高等数学超入门学习笔记

极限 百度百科 1.数列极限 百度百科 1.1 数列 1.2 数列极限 1.3 单调收敛原理 {xn}\{x_n\}{xn​}单调递增且{xn}\{x_n\}{xn​}有上界&#xff08;可以找到实数M使{xn}\{x_n\}{xn​}中任意一项小于M&#xff09;&#xff0c;{xn}\{x_n\}{xn​}收敛&#xff08;存在象限a&…