社区讨论
这个题双log只能过52吗
P11364[NOIP2024] 树上查询参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mieayulg
- 此快照首次捕获于
- 2025/11/25 16:17 3 个月前
- 此快照最后确认于
- 2025/11/25 17:24 3 个月前
我的代码
CPP#include <bits/stdc++.h>
using namespace std;
#define int long long
#define fr first
#define sc second
#define pii pair<int,int>
#define yes cout<<"Yes\n"
#define no cout<<"No\n"
#define fo(i,l,r) for(int i=l;i<=r;i++)
#define ro(i,r,l) for(int i=r;i>=l;i--)
const int N=5e5+5;
int n,Q,a[N];
namespace treelca{
vector<int>e[N];
int dep[N],fa[N],siz[N],son[N];
void dfs1(int u){
dep[u]=dep[fa[u]]+1;
siz[u]=1;
for (auto v:e[u]){
if (v==fa[u])
continue;
fa[v]=u;
dfs1(v);
siz[u]+=siz[v];
if (siz[v]>siz[son[u]])
son[u]=v;
}
}
int dfn[N],top[N],tip;
void dfs2(int u){
dfn[u]=++tip;
if (son[u]){
top[son[u]]=top[u];
dfs2(son[u]);
}
for (auto v:e[u]){
if (v==fa[u]||v==son[u])
continue;
top[v]=v;
dfs2(v);
}
}
void init(){
dfs1(1);
top[1]=1;
dfs2(1);
}
int lca(int x,int y){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]])
y=fa[top[y]];
else x=fa[top[x]];
}
return dep[x]>dep[y]?y:x;
}
}
using namespace treelca;
int out[N],mx,f[N][22];
pii val[N];
struct querynode{
int l,r,k,id;
}q[N],q2[N];
namespace sgm{
#define lc (x<<1)
#define rc (x<<1|1)
#define mid ((l+r)>>1)
struct node{
int ls,rs,mxs,len;
friend node operator+(node x,node y){
node rt;
if (x.ls==x.len)
rt.ls=x.ls+y.ls;
else rt.ls=x.ls;
if (y.rs==y.len)
rt.rs=y.rs+x.rs;
else rt.rs=y.rs;
rt.mxs=max(max(x.mxs,y.mxs),x.rs+y.ls);
rt.len=x.len+y.len;
return rt;
}
}d[N<<2];
int b[N];
void build(int x,int l,int r){
if (l==r){
d[x]={0,0,0,1};
return;
}
build(lc,l,mid);
build(rc,mid+1,r);
d[x]=d[lc]+d[rc];
}
void modify(int x,int l,int r,int t){
if (l==r){
b[l]^=1;
d[x]={b[l],b[l],b[l],1};
return;
}
if (t<=mid)
modify(lc,l,mid,t);
else modify(rc,mid+1,r,t);
d[x]=d[lc]+d[rc];
}
node query(int x,int l,int r,int ql,int qr){
if (ql<=l&&r<=qr)
return d[x];
if (ql<=mid&&qr>mid)
return query(lc,l,mid,ql,qr)+query(rc,mid+1,r,ql,qr);
if (ql<=mid)
return query(lc,l,mid,ql,qr);
return query(rc,mid+1,r,ql,qr);
}
#undef lc
#undef rc
#undef mid
}
using namespace sgm;
void solve(int ansl,int ansr,int ql,int qr,int vt){
if (ql>qr)
return;
// cout<<ansl<<' '<<ansr<<' '<<ql<<' '<<qr<<' '<<vt<<'\n';
// fo(i,1,n)
// cout<<b[i];
// cout<<'\n';
if (ansl==ansr){
fo(i,ql,qr)
out[q[i].id]=ansl;
return;
}
int mid=(ansl+ansr+1)>>1,tl=ql,tr=qr;
fo(i,ql,qr){
if (query(1,1,n,q[i].l,q[i].r).mxs>=q[i].k)
q2[tr--]=q[i];
else q2[tl++]=q[i];
}
fo(i,ql,qr)
q[i]=q2[i];
int qmid=tl-1,vtt=vt;
while (val[vt-1].fr>=(ansl+mid)/2)
modify(1,1,n,val[--vt].sc);
solve(ansl,mid-1,ql,qmid,vt);
while (vt<vtt)
modify(1,1,n,val[vt++].sc);
while (val[vt].fr<(ansr+mid+1)/2)
modify(1,1,n,val[vt++].sc);
solve(mid,ansr,qmid+1,qr,vt);
while (vt>vtt)
modify(1,1,n,val[--vt].sc);
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
fo(i,1,n-1){
int u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
init();
fo(i,1,n-1){
a[i]=dep[lca(i,i+1)];
val[i]={a[i],i};
mx=max(mx,a[i]);
// cout<<a[i]<<' ';
}
// cout<<'\n';
fo(i,1,n)
f[i][0]=dep[i];
fo(j,1,20)
fo(i,1,n-(1ll<<j)+1)
f[i][j]=max(f[i][j-1],f[i+(1ll<<j-1)][j-1]);
n--,sort(val+1,val+n+1);
build(1,1,n);
int vt=0;
fo(i,1,n)
if (val[i].fr>=(mx+2)/2){
vt=(vt?vt:i);
modify(1,1,n,val[i].sc);
}
cin>>Q;
int Q2=0;
fo(i,1,Q){
int l,r,k;
cin>>l>>r>>k;
if (k==1){
int t=log2(r-l+1);
out[i]=max(f[l][t],f[r-(1ll<<t)+1][t]);
}
else{
r--,k--;
q[++Q2]={l,r,k,i};
}
}
solve(1,mx,1,Q2,vt);
fo(i,1,Q)
cout<<out[i]<<'\n';
return 0;
}
提交记录 https://www.luogu.com.cn/record/249490572
回复
共 4 条回复,欢迎继续交流。
正在加载回复...