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

    题目大意:

    给你一颗有根树,点有权值,m次询问,每次问你某个点的子树中距离其不超过k的点的权值的最小值。(边权均为1,点权有可能重复,k值每次询问有可能不同,强制在线

    做法跟HDU那道题一样,开两颗线段树,一颗维护每个深度最小值,一颗维护每个值所在最低深度,合并第二个线段树的时候顺便修改第一个即可

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define M 100010
     6 using namespace std;
     7 int n,m,num,cnt,top,r,ans;
     8 int head[M],a[M],b[M],rt1[M],rt2[M],deep[M];
     9 int val[M<<8],ch[M<<8][2];
    10 struct point{int to,next;}e[M<<1];
    11 void add(int from,int to) {
    12     e[++num].next=head[from];
    13     e[num].to=to;
    14     head[from]=num;
    15 }
    16 int get(int x) {
    17     int l=1,r=top;
    18     while(l<=r) {
    19         int mid=(l+r)/2;
    20         if(b[mid]==x) return mid;
    21         if(b[mid]>x) r=mid-1;
    22         else l=mid+1; 
    23     }
    24 }
    25 int insert(int rt,int l,int r,int x,int v) {
    26     int node=++cnt;val[node]=min(val[rt],v);
    27     if(l==r) return node;
    28     int mid=(l+r)/2;
    29     ch[node][0]=ch[rt][0],ch[node][1]=ch[rt][1];
    30     if(x<=mid) ch[node][0]=insert(ch[rt][0],l,mid,x,v);
    31     else ch[node][1]=insert(ch[rt][1],mid+1,r,x,v);
    32     return node;
    33 }
    34 int merge1(int x,int y,int l,int r) {
    35     if(!x||!y) return x+y;
    36     int node=++cnt,mid=(l+r)/2;
    37     val[node]=min(val[x],val[y]);
    38     if(l==r) return node;
    39     ch[node][0]=merge1(ch[x][0],ch[y][0],l,mid);
    40     ch[node][1]=merge1(ch[x][1],ch[y][1],mid+1,r);
    41     return node;
    42 }
    43 int merge2(int x,int y,int l,int r,int id) {
    44     if(!x||!y) return x+y;
    45     int node=++cnt,mid=(l+r)/2;
    46     if(l==r) {
    47         val[node]=min(val[x],val[y]);
    48         rt1[id]=insert(rt1[id],1,n,val[node],l);
    49         return node;
    50     }
    51     ch[node][0]=merge2(ch[x][0],ch[y][0],l,mid,id);
    52     ch[node][1]=merge2(ch[x][1],ch[y][1],mid+1,r,id);
    53     return node;
    54 }
    55 int query(int node,int l,int r,int l1,int r1) {
    56     if(l1<=l&&r1>=r) return val[node];
    57     int mid=(l+r)/2,ans=1e9;
    58     if(l1<=mid) ans=min(ans,query(ch[node][0],l,mid,l1,r1));
    59     if(r1>mid) ans=min(ans,query(ch[node][1],mid+1,r,l1,r1));
    60     return ans;
    61 }
    62 void dfs(int x,int fa) {
    63     deep[x]=deep[fa]+1;
    64     rt1[x]=insert(0,1,n,deep[x],a[x]);
    65     rt2[x]=insert(0,1,n,a[x],deep[x]);
    66     for(int i=head[x];i;i=e[i].next)
    67         if(e[i].to!=fa) {
    68             dfs(e[i].to,x);
    69             rt1[x]=merge1(rt1[x],rt1[e[i].to],1,n);
    70             rt2[x]=merge2(rt2[x],rt2[e[i].to],1,n,x);
    71         }
    72 }
    73 int main() {
    74     memset(val,1,sizeof(val));
    75     scanf("%d%d",&n,&r);
    76     for(int i=1;i<=n;i++) 
    77         scanf("%d",&a[i]),b[++top]=a[i];
    78     sort(b+1,b+1+top);top=unique(b+1,b+1+top)-b-1;
    79     for(int i=1;i<=n;i++) a[i]=get(a[i]);
    80     for(int i=1;i<n;i++) {
    81         int a,b;scanf("%d%d",&a,&b);
    82         add(a,b),add(b,a);
    83     }
    84     dfs(r,0);scanf("%d",&m);
    85     for(int i=1;i<=m;i++) {
    86         int x,k;scanf("%d%d",&x,&k);
    87         x=(x+ans)%n+1,k=(k+ans)%n;
    88         printf("%d
    ",ans=b[query(rt1[x],1,n,deep[x],min(deep[x]+k,n))]);
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    HTTP RFC解析
    Symfony框架的笔记
    Swoole学习总结1
    PHP Socket 学习笔记一
    Js解决解除多次Ajax请求的事件
    Python 操作串口
    python 实现微信自动回复和好友签名分析
    杂谈1
    Vue.js 功课1
    微信API demo
  • 原文地址:https://www.cnblogs.com/Slrslr/p/10032935.html
Copyright © 2011-2022 走看看