zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      题目传送门;

      这个貌似是我这个蒟蒻做的第一道NOI系列的题了吧。。。这题的算法是树链剖分,其实基本上就是很常见的树剖+线段树,题目既然是要求每次安装或卸载改变的软件包的数目,那么就在每次操作前记录下线段树中根节点的权值,再进行修改,修改后的根节点的值与先前记录的值的差的绝对值就是改变的软件包的数目。思想并不复杂,但是这一类代码量比较大的题有很多细节要注意,这里我就不一一地说了。

      另外,这个题目中的软件包是从0开始标号的,为了方便操作,可以把所有软件包的标号都+1。

      下面是AC代码:

      (蒟蒻手写的代码效率也还行,最慢的点236ms)  

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int N=200010;
    int n,m,anum,depth[N],head[N];
    int xu[N],id,num[N],fa[N];
    int size[N],top[N],hson[N];
    int segtree[N<<2],sign[N<<2];
    struct Node{
      int to,next;
    }edge[N<<1];
    inline int read()
    {
      char ch=getchar();int num=0;bool flag=false;
      while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();}
      while(ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();}
      return flag?-num:num;
    }
    inline int Abs(int x)
    {return x>0?x:-x;}
    inline void add(int x,int y)
    {
      edge[++anum].to=y;
      edge[anum].next=head[x];
      head[x]=anum;
    }
    inline void dfs1(int u)
    {
      size[u]=1;
      for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa[u])continue;
        depth[v]=depth[u]+1;fa[v]=u;
        dfs1(v);size[u]+=size[v];
        if(!hson[u]||size[v]>size[hson[u]])
          hson[u]=v;
      }
    }
    inline void dfs2(int u,int nowtop)
    {
      xu[++id]=u;num[u]=id;top[u]=nowtop;
      if(!hson[u])return;dfs2(hson[u],nowtop);
      for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa[u]||v==hson[u])continue;
        dfs2(v,v);
      }
    }
    inline void pushup(int root)
    {segtree[root]=segtree[root<<1]+segtree[root<<1|1];}
    inline void pushdown(int root,int l,int r)
    {
      if(sign[root]!=-1){
        int mid=(l+r)>>1;
        segtree[root<<1]=(mid-l+1)*sign[root];
        segtree[root<<1|1]=(r-mid)*sign[root];
        sign[root<<1]=sign[root];
        sign[root<<1|1]=sign[root];
        sign[root]=-1;
      }
    }
    inline void build(int l,int r,int root)
    {
      segtree[root]=0;
      if(l==r)return;
      int mid=(l+r)>>1;
      build(l,mid,root<<1);
      build(mid+1,r,root<<1|1);
      pushup(root);
    }
    inline void update(int l,int r,int root,int L,int R,int C)
    {
      if(r<L||l>R)return;
      if(L<=l&&r<=R){
        segtree[root]=(r-l+1)*C;
        sign[root]=C;return;}
      int mid=(l+r)>>1;
      pushdown(root,l,r);
      if(L<=mid)update(l,mid,root<<1,L,R,C);
      if(R>mid)update(mid+1,r,root<<1|1,L,R,C);
      pushup(root);
    }
    inline void change(int x,int y,int val)
    {
      int fax=top[x],fay=top[y];
      while(fax!=fay){
        if(depth[fax]<depth[fay])
          {swap(fax,fay);swap(x,y);}
        update(1,n,1,num[fax],num[x],val);
        x=fa[fax];fax=top[x];
      }
      if(depth[x]>depth[y])swap(x,y);
      update(1,n,1,num[x],num[y],val);
    }
    void ready()
    {
      memset(head,-1,sizeof(head));
      memset(sign,-1,sizeof(sign));
      n=read();
      for(int i=1;i<n;i++){
        int x=read();
        add(i+1,x+1);
        add(x+1,i+1);
      }
      fa[1]=1;depth[1]=1;
      dfs1(1);dfs2(1,1);
      build(1,n,1);
    }
    void work()
    {
      m=read();char ka[10];
      for(int i=1;i<=m;i++){
        scanf("%s",ka);
        int t1=segtree[1];
        int x=read();x++;
        if(ka[0]=='i'){
          change(1,x,1);
          int t2=segtree[1];
          printf("%d
    ",Abs(t2-t1));
        }
        if(ka[0]=='u'){
          update(1,n,1,num[x],num[x]+size[x]-1,0);
          int t2=segtree[1];
          printf("%d
    ",Abs(t1-t2));
        }
      }
    }
    int main()
    {
      ready();
      work();
      return 0;
    }
  • 相关阅读:
    tomact配置
    cesium环境配置
    电脑上压缩文件不显示图标的解决办法
    MSCE C#官网一步步学习搬运9 第九章、用C++/CLI编写Addins
    MSCE | MDL二次开发知识点与遇到的问题记录
    MSCE C++官网一步步学习搬运7
    MSCE C++官网一步步学习搬运6
    geotools模块梳理
    geoserver 安全配置
    mapbox去除logo控件和attribution控件
  • 原文地址:https://www.cnblogs.com/cytus/p/8270642.html
Copyright © 2011-2022 走看看