zoukankan      html  css  js  c++  java
  • bzoj 4196 软件包管理器

    题目大意:

    一棵树,开始所有点权值为0 支持两种操作:

    ① 将它到根路径上所有点(包括自己与根)的权值都变为1 求点权被改变的点的个数

    ② 将它的子树内所有点以及自己的权值变为1 求点权被改变的点的个数

    思路:

    看懂了题之后就很裸了

    然后我因为pushdown的tag向下传递少打了右子树的“|1”调了好久

    orz

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<queue>
      9 #define inf 2139062143
     10 #define ll long long
     11 #define MAXN 101010 
     12 using namespace std;
     13 inline int read()
     14 {
     15     int x=0,f=1;char ch=getchar();
     16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
     17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 int nxt[MAXN<<1],fst[MAXN],n,to[MAXN<<1],Cnt;
     21 int cnt[MAXN],bl[MAXN],fa[MAXN],dep[MAXN],hsh[MAXN];
     22 struct data {int l,r,tag,sum;}tr[MAXN<<2];
     23 void add(int u,int v) {nxt[++Cnt]=fst[u],fst[u]=Cnt,to[Cnt]=v;}
     24 void dfs(int x)
     25 {
     26     cnt[x]=1;
     27     for(int i=fst[x];i;i=nxt[i])
     28     {
     29         if(to[i]==fa[x]) continue;
     30         fa[to[i]]=x,dep[to[i]]=dep[x]+1;
     31         dfs(to[i]);
     32         cnt[x]+=cnt[to[i]];
     33     }
     34 }
     35 void Dfs(int x,int anc)
     36 {
     37     int hvs=0;hsh[x]=++Cnt,bl[x]=anc;
     38     for(int i=fst[x];i;i=nxt[i])
     39         if(to[i]!=fa[x]&&cnt[to[i]]>cnt[hvs]) hvs=to[i];
     40     if(!hvs) return ;
     41     Dfs(hvs,anc);
     42     for(int i=fst[x];i;i=nxt[i])
     43         if(to[i]!=fa[x]&&to[i]!=hvs) Dfs(to[i],to[i]);
     44 }
     45 void build(int k,int l,int r)
     46 {
     47     tr[k].l=l,tr[k].r=r,tr[k].sum=tr[k].tag=0;
     48     if(l==r) return ;
     49     int mid=(l+r)>>1;
     50     build(k<<1,l,mid);
     51     build(k<<1|1,mid+1,r);
     52 }
     53 void pushdown(int k)
     54 {
     55     tr[k<<1].tag=tr[k<<1|1].tag=tr[k].tag;
     56     if(tr[k].tag==1) tr[k<<1].sum=tr[k<<1].r-tr[k<<1].l+1,tr[k<<1|1].sum=tr[k<<1|1].r-tr[k<<1|1].l+1;
     57     if(tr[k].tag==-1)  tr[k<<1].sum=tr[k<<1|1].sum=0;
     58     tr[k].tag=0;
     59 }
     60 void upd(int k,int a,int b,int x)
     61 {
     62     int l=tr[k].l,r=tr[k].r;
     63     if(a==l&&b==r) {if(x==1) tr[k].sum=r-l+1,tr[k].tag=1;else tr[k].sum=0,tr[k].tag=-1;return ;}
     64     if(tr[k].tag) pushdown(k);
     65     int mid=(l+r)>>1;
     66     if(mid>=b) upd(k<<1,a,b,x);
     67     else if(mid<a) upd(k<<1|1,a,b,x);
     68     else {upd(k<<1,a,mid,x);upd(k<<1|1,mid+1,b,x);}
     69     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
     70 }
     71 int query(int k,int a,int b)
     72 {
     73     int l=tr[k].l,r=tr[k].r;
     74     if(a==l&&b==r) return tr[k].sum;
     75     int mid=(l+r)>>1;
     76     if(tr[k].tag) pushdown(k);
     77     if(mid>=b) return query(k<<1,a,b);
     78     else if(mid<a) return query(k<<1|1,a,b);
     79     else return query(k<<1,a,mid)+query(k<<1|1,mid+1,b);
     80 }
     81 int main()
     82 {
     83     n=read();
     84     for(int i=2;i<=n;i++) {fa[i]=read()+1;add(i,fa[i]);add(fa[i],i);}
     85     dep[1]=1;
     86     dfs(1);Cnt=0;
     87     Dfs(1,1);
     88     build(1,1,n);
     89     int T=read();char ch[18];
     90     int a,res;
     91     while(T--)
     92     {
     93         scanf("%s",ch);a=read()+1,res=0;
     94         if(ch[0]=='i')
     95         {
     96             while(a!=0)
     97             {
     98                 res+=(hsh[a]-hsh[bl[a]]+1-query(1,hsh[bl[a]],hsh[a]));
     99                 upd(1,hsh[bl[a]],hsh[a],1);
    100                 a=fa[bl[a]];
    101             }
    102         }
    103         else
    104         {
    105             res+=query(1,hsh[a],hsh[a]+cnt[a]-1);
    106             upd(1,hsh[a],hsh[a]+cnt[a]-1,-1);
    107         }
    108         printf("%d
    ",res);
    109     }
    110 }
    View Code
  • 相关阅读:
    sql查询自然数判断
    esayswool_admin的3个坑
    debian安装easyswoole
    微软浏览器冲浪小游戏
    php程序的安装和composer
    图片搬运工
    热血高校这部电影中的内含文化
    Google日本語入力的使用方法,基本的快捷键。
    PHP截取两个指定字符中间的字符
    php去除字符串中的HTML标签
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8039729.html
Copyright © 2011-2022 走看看