zoukankan      html  css  js  c++  java
  • [CF893F] Subtree Minimum Query

    Description:

    给定一棵树,每次询问某点子树中到其不超过k的所有点的最小点权
    强制在线

    Hint:

    (n,mle 10^5)

    Solution:

    看到题目第一反应是以深度为下标,dfs序为版本建树

    然而不行,因为min不满足前缀可减

    所以我们换过来,每个(dep)建树表示(<=dep)所有点的权值

    在上面直接查x子树的min就好了

    貌似这题用线段树合并就是SBT......

    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int mxn=5e5+5,inf=1e9;
    int n,m,tot,cnt,rk[mxn],hd[mxn];
    
    inline int read() {
        char c=getchar(); int x=0,f=1;
        while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
        while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
        return x*f;
    }
    inline void chkmax(int &x,int y) {if(x<y) x=y;}
    inline void chkmin(int &x,int y) {if(x>y) x=y;}
    
    struct ed {
        int to,nxt;
    }t[mxn<<1];
    
    inline void add(int u,int v) {
        t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
    }
    
    int df,dep[mxn],lst[mxn],dfn[mxn],tr[mxn<<5],ls[mxn<<5],rs[mxn<<5],a[mxn],rt[mxn];
    
    void dfs(int u,int fa) {
        dep[u]=dep[fa]+1; dfn[u]=++df;
        for(int i=hd[u];i;i=t[i].nxt) {
            int v=t[i].to;
            if(v==fa) continue ;
            dfs(v,u);
        }
        lst[u]=df;
    }
    
    int cmp(int x,int y) {
        return dep[x]<dep[y];
    }
    
    void update(int las,int &p,int l,int r,int pos,int val) {
        p=++tot; 
        if(l==r) {tr[p]=min(tr[p],val);return ; }int mid=(l+r)>>1;
        if(pos<=mid) update(ls[las],ls[p],l,mid,pos,val),rs[p]=rs[las];
        else update(rs[las],rs[p],mid+1,r,pos,val),ls[p]=ls[las];
        tr[p]=min(tr[ls[p]],tr[rs[p]]);
    } 
    
    int query(int p,int l,int r,int ql,int qr) {
        if(!p) return inf;
        if(ql<=l&&r<=qr) return tr[p];
        int mid=(l+r)>>1; int res=inf;
        if(ql<=mid) chkmin(res,query(ls[p],l,mid,ql,qr));
        if(qr>mid) chkmin(res,query(rs[p],mid+1,r,ql,qr));
        return res;
    }
    
    int r;
    
    int main()
    {
        n=read(); r=read(); int u,v,p,q; memset(tr,0x3f,sizeof(tr));
        for(int i=1;i<=n;++i) rk[i]=i,a[i]=read();
        for(int i=1;i<n;++i) {
            u=read(); v=read();
            add(u,v); add(v,u);
        }
        dfs(r,0); int ans=0;
        sort(rk+1,rk+n+1,cmp);
        for(int i=1;i<=n;++i) 
            update(rt[dep[rk[i-1]]],rt[dep[rk[i]]],1,n,dfn[rk[i]],a[rk[i]]);
        m=read();
        for(int i=1;i<=m;++i) {
            p=(read()+ans)%n+1; q=(read()+ans)%n;
            printf("%d
    ",ans=query(rt[min(dep[p]+q,dep[rk[n]])],1,n,dfn[p],lst[p])); //注意特判深度超出最大深度
        }
        return 0;
    }
    
    
  • 相关阅读:
    python3 操作excel(读操作)
    display:inline-block;产生间隙解决方法
    vedio自定义样式
    angularjs路由
    移动端设置字体px转换rem的脚本
    div在不固定高度的情况下垂直或者水平居中
    css气泡地址和分享地址
    js点击按钮div显示,点击div或者body和按钮,div隐藏
    js倒计时跳转页面
    点击按钮div显示,点击div或者document,div隐藏
  • 原文地址:https://www.cnblogs.com/list1/p/10639564.html
Copyright © 2011-2022 走看看