「CF1491H」Yuezheng Ling and Dynamic Tree
根据弹飞绵羊的思路,考虑分块维护一个 表示 第一个不在当前块的祖先,设块长为 ,考虑如何求 和 的 ,我们可以用类似于树剖跳重链的方法在 求出。考虑如何修改,发现修改操作一定会使 减少,且 修改 次后一定有 ,所以暴力修改,当块内全有 时打个标记即可,时间复杂度为 ,块长取 即为 .
#include<bits/stdc++.h>
#define ll long long
#define PI pair<int,int>
#define PII pair< pair<int,int> , int >
#define fi first
#define se second
#define mp(x,y) make_pair(x,y)
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define MAXN (100005)
#define MAXB (355)
#define MOD (1000000007)
using namespace std;
template<typename type>
void read(type &x)
{
x=0;char ch=0;bool ff=0;
while(ch<'0'||ch>'9'){ff|=!(ch^'-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
x=ff?-x:x;
}
ll qpow(ll x,ll y)
{
ll res=1;
while(y)
{
if(y&1ll) res=res*x%MOD;
x=x*x%MOD,y>>=1ll;
}
return res;
}
bool vis[MAXN];
int n,q,lim;
int cnt[MAXB],f[MAXN],top[MAXN],idx[MAXN],l[MAXB],r[MAXB],tag[MAXB];
void rebuild(int x)
{
cnt[x]=0;
for(int i=l[x];i<=r[x];i++)
f[i]=max(f[i]-tag[x],1);
tag[x]=0;
for(int i=l[x];i<=r[x];i++)
{
if(f[i]<l[x]) top[i]=f[i],++cnt[x];
else top[i]=top[f[i]];
}
}
void init()
{
lim=300;
for(int i=1;i<=n;i++)
{
idx[i]=(i+lim-1)/lim;
l[idx[i]]=l[idx[i]]?l[idx[i]]:i;
r[idx[i]]=i;
}
for(int i=1;i<=idx[n];i++)
rebuild(i);
return;
}
void modify(int L,int R,int x)
{
if(idx[L]^idx[R])
{
for(int i=L;i<=r[idx[L]];i++)
f[i]=max(f[i]-x,1);
rebuild(idx[L]);
for(int i=idx[L]+1;i<idx[R];i++)
{
if(cnt[i]<r[i]-l[i]+1)
{
for(int j=l[i];j<=r[i];j++)
f[j]=max(f[j]-x,1);
rebuild(i);
}
else tag[i]=min(tag[i]+x,n);
}
for(int i=l[idx[R]];i<=R;i++)
f[i]=max(f[i]-x,1);
rebuild(idx[R]);
}
else
{
for(int i=L;i<=R;i++)
f[i]=max(f[i]-x,1);
rebuild(idx[L]);
}
}
int topfa(int u){return max(top[u]-tag[idx[u]],1);}
int LCA(int u,int v)
{
while(1)
{
if(idx[u]<idx[v]) swap(u,v);
if(idx[u]^idx[v]) u=topfa(u);
else
{
if(topfa(u)^topfa(v)) u=topfa(u),v=topfa(v);
else break;
}
}
while(u^v)
{
if(u<v) swap(u,v);
u=max(f[u]-tag[idx[u]],1);
}
return u;
}
int main()
{
read(n),read(q);
for(int i=2;i<=n;i++)
read(f[i]);
init();
for(int tq=1;tq<=q;tq++)
{
int opt;
read(opt);
if(!(opt^1))
{
int l,r,x;
read(l),read(r),read(x);
modify(l,r,x);
f[1]=0,top[1]=0;
}
if(!(opt^2))
{
int u,v;
read(u),read(v);
printf("%d\n",LCA(u,v));
}
}
}
作者:littlepinkpig
出处:https://www.cnblogs.com/littlepinkpig/p/17747131.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
你可以在这里自定义其他内容
作者:littlepinkpig
出处:https://www.cnblogs.com/littlepinkpig/p/17747131.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
DS
, 「Codeforces」做题记录
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现