• CF893F Subtree Minimum Query(主席树)


    我们发现要求的答案是depth[u]-min(depth[u]+k,mx)之间的属于他子树的最小值,mx是最深的深度

    在线算法,不难想到用主席树对深度建树,这样就可以求取区间深度的信息,区间min没有可减性,但是并不影响本题做法

    因为我们只需要查找指定dfs序区间中的答案即可,这样才是他子树中的答案,在前缀的深度当中,只有子树的答案才会被用来更新

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    const int mod=1e9+7;
    int rt[N];
    int a[N];
    int depth[N];
    int st[N],ed[N],times;
    int h[N],ne[N],e[N],idx;
    vector<int> num[N];
    int mx;
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    struct node{
        int l,r;
        int mi;
    }tr[N*30];
    void dfs(int u,int fa){
        int i;
        st[u]=++times;
        num[depth[u]].push_back(u);
        mx=max(mx,depth[u]);
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            depth[j]=depth[u]+1;
            dfs(j,u);
        }
        ed[u]=times;
    }
    void build(int &p,int l,int r){
        p=++idx;
        tr[p].mi=1e9;
        if(l==r)
            return ;
        int mid=l+r>>1;
        build(tr[p].l,l,mid);
        build(tr[p].r,mid+1,r);
    }
    void insert(int &p,int q,int l,int r,int pos,int x){
        p=++idx;
        tr[p]=tr[q];
        tr[p].mi=min(tr[p].mi,x);
        if(l==r)
            return ;
        int mid=l+r>>1;
        if(pos<=mid)
            insert(tr[p].l,tr[q].l,l,mid,pos,x);
        else
            insert(tr[p].r,tr[q].r,mid+1,r,pos,x);
    }
    int query(int p,int l,int r,int L,int R){
        if(L<=l&&R>=r){
            return tr[p].mi;
        }
        int mid=l+r>>1;
        int ans=1e9;
        if(L<=mid)
            ans=min(ans,query(tr[p].l,l,mid,L,R));
        if(R>mid)
            ans=min(ans,query(tr[p].r,mid+1,r,L,R));
        return ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        int i;
        int n,p;
        cin>>n>>p;
        memset(h,-1,sizeof h);
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        for(i=1;i<n;i++){
            int x,y;
            cin>>x>>y;
            add(x,y);
            add(y,x);
        }
        depth[p]=1;
        dfs(p,-1);
        build(rt[0],1,n);
        for(i=1;i<=mx;i++){
            rt[i]=rt[i-1];
            for(auto x:num[i])
            insert(rt[i],rt[i],1,n,st[x],a[x]);
        }
        int last=0;
        int m;
        cin>>m;
        while(m--){
            int p,q;
            cin>>p>>q;
            int x=(p+last)%n+1;
            int k=(q+last)%n;
            last=query(rt[min(depth[x]+k,mx)],1,n,st[x],ed[x]);
            cout<<last<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    avrdude: stk500_getsync(): not in sync: resp=0x00
    PCB封装技术
    C/C++基础问题归集
    mf210v 端口的映射
    alsamixer 在音频子系统的使用
    rp2836 网卡以及串口与接插件位置关系
    RP2837 IN1-IN2 对应关系 2路DI
    RP2837 OUT1-OUT2 对应关系 2路DO
    RP2836 板卡信息标识
    RP2836 OUT0-OUT7 对应关系
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14100239.html
Copyright © 2020-2023  润新知