分散层叠思想:
将后续信息融入到当前查询中,利用当前查询结果定位后续查询结果
四毛子思想:
对数分块,直接打表所有可能面对的情况,最后分块查表即可
+-1RMQ问题,01矩阵乘法问题,LCA,配合笛卡尔树可以完成任意RMQ问题
(突然发现自己以前出的一道无结合律的线段树就是四毛子)
最小差值生成树:
wssb,排序直接加边,破圈法用当前边代替换上最小边,统计一下存在的边极差即可
[NOI2014]魔法森林:
枚举a,把所有小于a的边加入,维护关于b的最小生成树,维护1~n路径上最大的b值
[BJOI2014]大融合:
LCT,统计一下删边后两连通块的大小
LCT+树链剖分
Access操作时把LCT虚变实的边的下子树权值-1,实变虚的边的下子树的权值+1
本质上是由LCT确定维护的区间,然后在dfs序的线段树上维护最大值
一个防止findroot的方法,在LCT中维护dep最小的点的编号
代码:(老了,首先是fir[u]写成了fir[p],调了一个小时,然后是线段树懒标记下传写错,又调了一个小时,再是rot少写了更新z节点的语句,又调了半个小时,麻中麻)
- #include
- #include
- #include
- using namespace std;
- inline int gi()
- {
- char c;int num=0,flg=1;
- while((c=getchar())<'0'||c>'9')if(c=='-')flg=-1;
- while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();}
- return num*flg;
- }
- #define N 100005
- int to[2*N],nxt[2*N],fir[N],cnt;
- void adde(int a,int b)
- {
- to[++cnt]=b;nxt[cnt]=fir[a];fir[a]=cnt;
- }
- int siz[N],son[N],top[N],fa[N],dep[N];
- int dfn[N],num[N],dc;
- void dfs1(int u,int f)
- {
- fa[u]=f;
- dep[u]=dep[f]+1;
- siz[u]=1;
- for(int v,p=fir[u];p;p=nxt[p]){
- if((v=to[p])!=f){
- dfs1(v,u);
- siz[u]+=siz[v];
- if(siz[son[u]]
- son[u]=v;
- }
- }
- }
- void dfs2(int u)
- {
- dfn[u]=++dc;num[dc]=u;
- if(son[u]){
- top[son[u]]=top[u];
- dfs2(son[u]);
- }
- for(int v,p=fir[u];p;p=nxt[p]){
- v=to[p];
- if(v!=son[u]&&v!=fa[u]){
- top[v]=v;
- dfs2(v);
- }
- }
- }
- int LCA(int u,int v)
- {
- while(top[u]!=top[v]){
- if(dep[top[u]]
- swap(u,v);
- u=fa[top[u]];
- }
- return dep[u]
- }
- struct node{
- int l,r,mx,la;
- }a[4*N];
- void pushup(int i)
- {
- a[i].mx=max(a[i<<1].mx,a[i<<1|1].mx);
- }
- void build(int i,int l,int r)
- {
- a[i].l=l;a[i].r=r;
- if(l==r){
- a[i].mx=dep[num[l]];
- return;
- }
- int mid=(l+r)>>1;
- build(i<<1,l,mid);
- build(i<<1|1,mid+1,r);
- pushup(i);
- }
- void pushdown(int i)
- {
- if(a[i].l==a[i].r)return;
- if(a[i].la){
- a[i<<1].mx+=a[i].la;
- a[i<<1|1].mx+=a[i].la;
- a[i<<1].la+=a[i].la;
- a[i<<1|1].la+=a[i].la;
- a[i].la=0;
- }
- }
- void update(int i,int l,int r,int k)
- {
- if(a[i].l>r||a[i].r
return; - pushdown(i);
- if(l<=a[i].l&&a[i].r<=r){
- a[i].mx+=k;
- a[i].la+=k;
- return;
- }
- update(i<<1,l,r,k);
- update(i<<1|1,l,r,k);
- pushup(i);
- }
- int query(int i,int l,int r)
- {
- if(a[i].l>r||a[i].r
return 0; - pushdown(i);
- if(l<=a[i].l&&a[i].r<=r)
- return a[i].mx;
- return max(query(i<<1,l,r),query(i<<1|1,l,r));
- }
- namespace LCT{
- int ch[N][2],fa[N],mipos[N];
- void pushup(int x)
- {
- mipos[x]=x;
- if(ch[x][0]&&dep[mipos[ch[x][0]]]
- mipos[x]=mipos[ch[x][0]];
- if(ch[x][1]&&dep[mipos[ch[x][1]]]
- mipos[x]=mipos[ch[x][1]];
- }
- bool pdc(int x){return ch[fa[x]][1]==x;}
- bool pdr(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
- void rot(int x)
- {
- int y=fa[x],z=fa[y];
- bool flg=pdc(x);
- if(!pdr(y)) ch[z][pdc(y)]=x;
- if(ch[y][flg]=ch[x][flg^1])
- fa[ch[y][flg]]=y;
- ch[x][flg^1]=y;
- fa[y]=x;fa[x]=z;
- pushup(y);pushup(x);
- }
- void splay(int x,int y)
- {
- for(;!pdr(x);rot(x))
- if(!pdr(fa[x]))
- rot(pdc(x)==pdc(fa[x])?fa[x]:x);
- }
- int findroot(int x)
- {
- while(ch[x][0])x=ch[x][0];
- return x;
- }
- void Access(int x)
- {
- int tmp=0;
- for(;x;x=fa[x]){
- splay(x,0);
- if(ch[x][1]){
- int rt=mipos[ch[x][1]];
- //int rt=findroot(ch[x][1]);
- update(1,dfn[rt],dfn[rt]+siz[rt]-1,1);
- }
- if(tmp){
- int rt=mipos[tmp];
- //int rt=findroot(tmp);
- update(1,dfn[rt],dfn[rt]+siz[rt]-1,-1);
- }
- ch[x][1]=tmp;
- pushup(x);
- tmp=x;
- }
- }
- }
- int main()
- {
- int n,m,x,y,i,op;
- n=gi();m=gi();
- for(i=1;i
- x=gi();y=gi();
- adde(x,y);adde(y,x);
- }
- dfs1(1,0);
- top[1]=1;
- dfs2(1);
- build(1,1,n);
- for(i=1;i<=n;i++)
- LCT::fa[i]=fa[i];
- while(m--){
- op=gi();
- if(op==1){
- x=gi();
- LCT::Access(x);
- }
- else if(op==2){
- x=gi();y=gi();
- int lca=LCA(x,y);
- int ans=query(1,dfn[x],dfn[x])+query(1,dfn[y],dfn[y])-2*query(1,dfn[lca],dfn[lca])+1;
- printf("%d\n",ans);
- }
- else{
- x=gi();
- printf("%d\n",query(1,dfn[x],dfn[x]+siz[x]-1));
- }
- }
- }
-
相关阅读:
立创EDA仿真入门2 实战全桥整流
Day41—— 343. 整数拆分 96.不同的二叉搜索树 (动规)
「面经分享」小米java岗二面面经,已拿offer
Cookie的使用(基于js-cookie插件)
聊一聊对“事务”的理解
【vue3】12.跟着官网学习vue3-侦听器,watch方法
基于多模态知识图谱的多模态推理-MR-MKG
centos 8 yum源不能使用问题
最小可用产品MVP,投石问路
Oracle数据库 on duplicate key update功能
-
原文地址:https://blog.csdn.net/C20180602_csq/article/details/126091627