zoukankan      html  css  js  c++  java
  • [Ynoi2012]D1T3

    https://www.luogu.org/problemnew/show/P5311

    题解

    先把点分树建出来。

    对于吗,每一个询问((l,r,x)),我们对于x要找到它在点分树上最靠上的父亲节点使得两点之间的点在(l sim r)中。

    然后问题就变成了从一个根出发,可以经过(l sim r)的点,能访问的颜色个数。

    那么因为有了点分树,所以我们对于每个点(dfs)它的子树的复杂度是对的。

    然后对于每个根,我们求出它的子树里的所有点的到根的路径上的编号最大最小值,然后考虑这个点产生贡献的条件,发现就是个二维偏序。

    但是还有相同颜色算两边的情况,这个在扫描线的时候用单调性去重就好了,具体来说对于(r)都在合法范围内的点,(l)更大越优,所以我们只需要保留最大的(l)就好了。

    代码

    #include<bits/stdc++.h>
    #define N 100009
    #define mm make_pair
    using namespace std;
    typedef long long ll;
    vector<int>fa[N];
    vector<pair<int,int> >v[N];
    bool vis[N];
    int tot,head[N],dp[N],ans[N],size[N],root,tong[N],a[N],n,m,sum;
    inline ll rd(){
      ll x=0;char c=getchar();bool f=0;
      while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
      while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
      return f?-x:x;
    }
    struct edge{
      int n,to;
    }e[N<<1];
    struct BIT{
      int tr[N];
      inline void add(int x,int y){while(x)tr[x]+=y,x-=x&-x;}
      inline int query(int x){int ans=0;while(x<=n)ans+=tr[x],x+=x&-x;return ans;}
    }T;
    struct node{
      int id,l,r,opt;
      inline bool operator <(const node &b)const{
        if(r!=b.r)return r<b.r;
        return opt<b.opt;  
      }
    };
    vector<node>b[N];
    vector<node>::iterator it;
    inline void add(int u,int v){
      e[++tot].n=head[u];e[tot].to=v;head[u]=tot;
    }
    void getroot(int u,int fa){
      dp[u]=0;size[u]=1;
      for(int i=head[u];i;i=e[i].n)if(!vis[e[i].to]&&e[i].to!=fa){
          int v=e[i].to;
          getroot(v,u);
          size[u]+=size[v];
          dp[u]=max(dp[u],size[v]);
      }
      dp[u]=max(dp[u],sum-size[u]);
      if(dp[u]<dp[root])root=u;
    }
    void getsize(int u,int fa){
      size[u]=1;
      for(int i=head[u];i;i=e[i].n)if(!vis[e[i].to]&&e[i].to!=fa){
        int v=e[i].to;
        getsize(v,u);
        size[u]+=size[v];
      }
    }
    void work(int u,int ff,int ma,int mi,int top){
      ma=max(ma,u);mi=min(mi,u);
      fa[u].push_back(top);
      v[u].push_back(mm(mi,ma));
      for(int i=head[u];i;i=e[i].n)if(e[i].to!=ff&&!vis[e[i].to]){
        int v=e[i].to;
        work(v,u,ma,mi,top);
      }
    }
    void getcalc(int u,int fa,int mi,int ma){
      mi=min(mi,u);ma=max(ma,u);
      b[root].push_back(node{a[u],mi,ma,0});
      for(int i=head[u];i;i=e[i].n)if(!vis[e[i].to]&&e[i].to!=fa){
        int v=e[i].to;
        getcalc(v,u,mi,ma);
      }
    }
    void solve(int u){
      vis[u]=1;
      getcalc(u,0,u,u);
      v[u].push_back(mm(u,u));fa[u].push_back(u);
      for(int i=head[u];i;i=e[i].n)if(!vis[e[i].to]){
        int v=e[i].to;
        root=n+1;sum=size[v];
        getroot(v,u);getsize(root,0);
        work(v,0,u,u,u);
        solve(root);
      }
    }
    int main(){
      n=rd();m=rd();
      for(int i=1;i<=n;++i)a[i]=rd();
      int x,y;
      for(int i=1;i<n;++i){
        x=rd();y=rd();
        add(x,y);add(y,x);
      }
      root=n+1;sum=n;dp[root]=n+1;
      getroot(1,0);getsize(root,0);
      solve(root);
      int l,r;
      for(int i=1;i<=m;++i){
        l=rd();r=rd();x=rd();
        for(int j=0;j<fa[x].size();++j){
          int y=fa[x][j],ls=v[x][j].first,rs=v[x][j].second;
          if(ls>=l&&rs<=r){x=y;break;}
        }
        b[x].push_back(node{i,l,r,1});
      }
      for(int i=1;i<=n;++i){
        sort(b[i].begin(),b[i].end());
        for(it=b[i].begin();it!=b[i].end();++it){
            if(!it->opt){
              if(tong[it->id]<it->l){
                if(tong[it->id])T.add(tong[it->id],-1);
                T.add(it->l,1);
                tong[it->id]=it->l;
              }
            }
            else{
              ans[it->id]=T.query(it->l);
            }
        }
        for(it=b[i].begin();it!=b[i].end();++it)
          if(!it->opt){
            if(tong[it->id])T.add(tong[it->id],-1),tong[it->id]=0;
          }
        b[i].clear();
      }
      for(int i=1;i<=m;++i)printf("%d
    ",ans[i]);
      return 0;
    }
    
  • 相关阅读:
    JavaScript基础学习篇
    js,html,css注释大集合
    JS中的专业术语
    BFC给我的帮助以及对hasLayout的认识
    框架
    PHP echo和print语句
    PHP变量
    PHP语法
    PHP入门
    SQLite学习网址
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10934969.html
Copyright © 2011-2022 走看看