zoukankan      html  css  js  c++  java
  • 【NOI2015】软件包管理器

    NOI2015的试题,一道树链剖分的模板题
    主要过程:树剖完成后对线段树进行区间修改,区间查询。
    代码较长,很考验代码能力

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 typedef long long ll;
      5 inline int abs(int x) {
      6     return x>0?x:-x;
      7 }
      8 inline int read() {
      9     int ret=0,f=1;
     10     char c=getchar();
     11     while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
     12     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
     13     return ret*f;
     14 }
     15 using namespace std;
     16 int n,q;
     17 struct edge {
     18     int next,to;
     19 }a[100010<<1];
     20 int num,head[100010<<1];
     21 char in[100];
     22 inline void add(int from,int to) {
     23     a[++num].next=head[from]; a[num].to=to; head[from]=num;
     24     swap(from,to);
     25     a[++num].next=head[from]; a[num].to=to; head[from]=num;
     26 }
     27 int fa[100010],d[100010],seg[100010],rev[100010],top[100010],son[100010];
     28 int data[100010<<2],tag[100010<<2],size[100010];
     29 void dfs1(int u,int f) {
     30     d[u]=d[f]+1;
     31     fa[u]=f;
     32     size[u]=1;
     33     for(int i=head[u];i;i=a[i].next) {
     34         int v=a[i].to;
     35         if(v==f) continue ;
     36         dfs1(v,u);
     37         size[u]+=size[v];
     38         if(size[v]>size[son[u]]) son[u]=v;
     39     }
     40 }
     41 void dfs2(int u,int fa) {
     42     if(son[u]) {
     43         seg[son[u]]=++seg[0];
     44         rev[seg[0]]=son[u];
     45         top[son[u]]=top[u];
     46         dfs2(son[u],u);
     47     }
     48     for(int i=head[u];i;i=a[i].next) {
     49         int v=a[i].to;
     50         if(!top[v]) {
     51             seg[v]=++seg[0];
     52             top[v]=v;
     53             rev[seg[0]]=v;
     54             dfs2(v,u);
     55         }
     56     }
     57 }
     58 void build(int now,int l,int r) {
     59     tag[now]=-1;
     60     if(l==r) {
     61         tag[now]=data[now]=0;
     62         return ;
     63     }
     64     int mid=l+r>>1;
     65     build(now<<1,l,mid);
     66     build(now<<1|1,mid+1,r);
     67 }
     68 void pushdown(int now,int len) {
     69     if(tag[now]==-1) return ;
     70     tag[now<<1]=tag[now<<1|1]=tag[now];
     71     data[now<<1]=tag[now]*(len-(len>>1));
     72     data[now<<1|1]=tag[now]*(len>>1);
     73     tag[now]=-1;
     74 }
     75 void updata(int now,int l,int r,int x,int y,int val) {
     76     if(x<=l&&r<=y) {
     77         tag[now]=val;
     78         data[now]=val*(r-l+1);
     79         return ;
     80     }
     81     pushdown(now,r-l+1);
     82     int mid=l+r>>1;
     83     if(x<=mid) updata(now<<1,l,mid,x,y,val);
     84     if(y>mid) updata(now<<1|1,mid+1,r,x,y,val);
     85     data[now]=data[now<<1]+data[now<<1|1];
     86 }
     87 void find(int x,int y) {
     88     while(top[x]!=top[y]) {
     89         if(d[top[x]]<d[top[y]]) swap(x,y);
     90         updata(1,1,seg[0],seg[top[x]],seg[x],1);
     91         x=fa[top[x]];
     92     }
     93     if(d[x]>d[y]) swap(x,y);
     94     updata(1,1,seg[0],seg[x],seg[y],1);
     95 }
     96 int main() {
     97     n=read();
     98     for(int i=2;i<=n;i++) add(i,read()+1);
     99     dfs1(1,0);
    100     seg[0]=seg[1]=rev[1]=top[1]=1;
    101     dfs2(1,0);
    102     build(1,1,seg[0]);
    103     q=read();
    104     while(q--) {
    105         scanf("%s",in+1);
    106         int x=read()+1;
    107         if(in[1]=='i') {
    108             int sum1=data[1];
    109             find(1,x);
    110             int sum2=data[1];
    111             printf("%d
    ",abs(sum1-sum2));
    112         }
    113         else {
    114             int sum1=data[1];
    115             updata(1,1,seg[0],seg[x],seg[x]+size[x]-1,0);
    116             int sum2=data[1];
    117             printf("%d
    ",abs(sum1-sum2));
    118         }
    119     }
    120     return 0;
    121 }
    AC Code

    注意线段树的标记操作

  • 相关阅读:
    笔记
    作用域及this指向案例总结
    笔记
    JS 事件(捕获和冒泡 兼容性写法)
    tab标签
    笔记
    JS入门(10.16)
    JS入门(10.15)
    关键渲染路径
    Practice1小学四则运算(改进)
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10541123.html
Copyright © 2011-2022 走看看