数据结构 杂题选做

数据结构科技树 \(=\emptyset\) 补一补

主席树

P3834 【模板】可持久化线段树 2

板子。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline 
#define gc getchar
#define pc putchar
#define mid (l+r>>1)
const int N=2e5+5;
const int M=1e5+5;
const int inf=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,a[N],b[N],rt[N],l,r,k;
struct SGT{
    int s[N<<5],ls[N<<5],rs[N<<5],cnt;
    inl void build(int &k,int l,int r){
        k=++cnt;
        if(l==r)return;
        build(ls[k],l,mid);
        build(rs[k],mid+1,r);
    }
    inl void update(int &now,int pst,int l,int r,int x){
        now=++cnt,s[now]=s[pst]+1,ls[now]=ls[pst],rs[now]=rs[pst];
        if(l==r)return;
        if(x<=mid)update(ls[now],ls[pst],l,mid,x);
        else update(rs[now],rs[pst],mid+1,r,x);
    }
    inl int query(int now,int pst,int l,int r,int k){
        if(l==r)return l;
        if(s[ls[now]]-s[ls[pst]]>=k)return query(ls[now],ls[pst],l,mid,k);
        else return query(rs[now],rs[pst],mid+1,r,k-(s[ls[now]]-s[ls[pst]]));
    }
}tree;
signed main(){
    n=read();m=read();
    for(int i=1;i<=n;i++)a[i]=b[i]=read();
    sort(b+1,b+n+1);
    int t=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+t+1,a[i])-b;
    tree.build(rt[0],1,t);
    for(int i=1;i<=n;i++)tree.update(rt[i],rt[i-1],1,t,a[i]);
    while(m--){
        l=read(),r=read(),k=read();
        writel(b[tree.query(rt[r],rt[l-1],1,t,k)]);
    }
    return 0;
}

P3899 [湖南集训] 更为厉害

考虑 \(b\) 所在位置:

1.在 \(a\) 到根的路径上 \(c\) 只可能是 \(a\) 子树内的点 答案 \(min(dep[a],k)*(siz[a]-1)\)

2.在 \(a\) 子树内 \([dep[a]+1,dep[a]+k]\) 的点 每个点贡献为 \(siz[b]-1\)

可以用主席树维护:下标维护深度 子树内查询即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline 
#define int ll
#define gc getchar
#define pc putchar
#define mid (l+r>>1)
const int N=3e5+5;
const int M=1e5+5;
const int inf=0x7fffffff;
const int mod=998244353;
const double eps=1e-8;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,q,u,v,dep[N],siz[N],rt[N],dfn[N],dfs_clock,rev[N],ans,p,k;
int head[N],nxt[N<<1],to[N<<1],cnt;
struct seg_tree{
    int s[N<<5],ls[N<<5],rs[N<<5],cnt;
    inl void build(int &k,int l,int r){
        k=++cnt;
        if(l==r)return;
        build(ls[k],l,mid);
        build(rs[k],mid+1,r);
    }
    inl void update(int &k,int pst,int l,int r,int x,int v){
        k=++cnt,s[k]=s[pst]+v,ls[k]=ls[pst],rs[k]=rs[pst];
        if(l==r)return;
        if(x<=mid)update(ls[k],ls[pst],l,mid,x,v);
        else update(rs[k],rs[pst],mid+1,r,x,v);
    }
    inl int query(int k,int pst,int l,int r,int x,int y){
        if(x<=l&&r<=y)return s[k]-s[pst];
        int ans=0;
        if(x<=mid)ans+=query(ls[k],ls[pst],l,mid,x,y);
        if(y>mid)ans+=query(rs[k],rs[pst],mid+1,r,x,y);
        return ans;
    }
}SGT;
inl void add(int u,int v){
    nxt[++cnt]=head[u];
    to[cnt]=v;
    head[u]=cnt;
}
inl void dfs1(int x,int fa){
    dfn[x]=++dfs_clock;
    rev[dfs_clock]=x;siz[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa)continue;
        dep[y]=dep[x]+1;
        dfs1(y,x);
        siz[x]+=siz[y];
    }
}
inl void dfs2(int x,int fa){
    SGT.update(rt[x],rt[rev[dfn[x]-1]],1,n,dep[x],siz[x]-1);
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa)continue;
        dfs2(y,x);
    }
}
signed main(){
    n=read();q=read();
    for(int i=1;i<=n-1;i++){
        u=read();v=read();
        add(u,v);add(v,u);
    }dep[0]=-1;dfs1(1,0);
    SGT.build(rt[0],1,n);
    dfs2(1,0);
    while(q--){
        p=read();k=read();
        ans=min(dep[p],k)*(siz[p]-1);
        ans+=SGT.query(rt[rev[dfn[p]+siz[p]-1]],rt[p],1,n,dep[p]+1,min(n,dep[p]+k));
        writel(ans);
    }
    return 0;
}
posted @ 2023-10-27 15:55  xiang_xiang  阅读(13)  评论(0)    收藏  举报