社区讨论

这个题双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 条回复,欢迎继续交流。

正在加载回复...