• BZOJ1103 [POI2007]大都市meg(DFS序)


    题目:一颗树,单边修改,链上查询。。实际上链是根到结点的链。网上好像有其他做法,我的想法是这样的:

    先不看修改,毫无疑问查询只是查询结点的深度;而修改一条边会有什么影响:影响是且只是以边上深度最深结点为根的子树。

    所以就是DFS序了。把子树转化为区间,然后用区间修改、单点查询的线段树维护。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define MAXN 255555
     6 struct Edge{
     7     int v,nxt;
     8 }edge[MAXN]; 
     9 int n,NE,head[MAXN];
    10 void addEdge(int u,int v){
    11     edge[NE].v=v; edge[NE].nxt=head[u]; head[u]=NE++;
    12 }
    13 
    14 int dep[MAXN],l[MAXN],r[MAXN],stack[MAXN],odr;
    15 void dfs(){
    16     int top=0;
    17     stack[++top]=1;
    18     while(top){
    19         int u=stack[top];
    20         if(l[u]){
    21             r[u]=odr; --top;
    22             continue; 
    23         }
    24         l[u]=++odr;
    25         for(int i=head[u]; i!=-1; i=edge[i].nxt){
    26             int v=edge[i].v;
    27             stack[++top]=v;
    28             dep[v]=dep[u]+1;
    29         }
    30     }
    31 }
    32 
    33 int tree[MAXN<<2],N,x,y;
    34 void update(int i,int j,int k){
    35     if(x<=i&&j<=y){
    36         ++tree[k];
    37         return;
    38     }
    39     if(tree[k]){
    40         tree[k<<1]+=tree[k]; tree[k<<1|1]+=tree[k];
    41         tree[k]=0;
    42     }
    43     int mid=i+j>>1;
    44     if(x<=mid) update(i,mid,k<<1);
    45     if(y>mid) update(mid+1,j,k<<1|1);
    46 }
    47 int query(int i,int j,int k){
    48     if(i==j) return tree[k];
    49     if(tree[k]){
    50         tree[k<<1]+=tree[k]; tree[k<<1|1]+=tree[k];
    51         tree[k]=0;
    52     }
    53     int mid=i+j>>1;
    54     if(x<=mid) return query(i,mid,k<<1);
    55     return query(mid+1,j,k<<1|1);
    56 }
    57 
    58 int main(){
    59     int m,a,b;
    60     char op[11];
    61     memset(head,-1,sizeof(head));
    62     scanf("%d",&n);
    63     for(int i=1; i<n; ++i){
    64         scanf("%d%d",&a,&b);
    65         if(a>b) swap(a,b);
    66         addEdge(a,b);
    67     }
    68     dfs();
    69     for(N=1; N<odr; N<<=1);
    70     scanf("%d",&m);
    71     m+=n-1;
    72     while(m--){
    73         scanf("%s",op);
    74         if(op[0]=='W'){
    75             scanf("%d",&a);
    76             x=l[a];
    77             printf("%d
    ",dep[a]-query(1,N,1));
    78         }else{
    79             scanf("%d%d",&a,&b);
    80             if(a<b) a=b;
    81             x=l[a]; y=r[a];
    82             update(1,N,1);
    83         }
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Arduino 封装库
    Arduino 学习
    Linux和UNIX监控
    mysql语句:批量更新多条记录的不同值[转]
    datagridview设置currentrow为指定的某一行[转]
    WeifenLuo组件中如何设置停靠窗体的宽度
    Win7 64位 Visio反向工程(MySQL)
    Castle.ActiveRecord (V3.0.0.130)
    位运算(2)——Number of 1 Bits
    位运算(1)——Hamming Distance
  • 原文地址:https://www.cnblogs.com/WABoss/p/4873944.html
Copyright © 2020-2023  润新知