zoukankan      html  css  js  c++  java
  • 20182019-acmicpc-asia-dhaka-regional F .Path Intersection 树链剖分

    直接进行树链剖分,每次对路径区间内的所有点值+1,线段树进行维护,然后查询线段树的最大值的个数!!!

    查询线段树区间最大值个数,可以先维护区间和,在维护区间最值,如果区间和等于区间最值乘以区间长度,那么直接返回长度!!!

    清空的时候,直接减去,不要直接重新建树

    #include<bits/stdc++.h>
    #define LL long long
    #define lson rt<<1
    #define rson rt<<1|1
    using namespace std;
    const int MAXN = 2e5+6;
    struct node{
      int l,r;
      int sum,laze;
      int maxx;
    }tree[MAXN<<2];
    struct edge{
       int Next,to;
    }e[MAXN<<1];
    int head[MAXN];
    int siz[MAXN];
    int top[MAXN];
    int son[MAXN];
    int d[MAXN];
    int fa[MAXN];
    int id[MAXN];
    int sz[MAXN];
    int uu[55],vv[55];
    int cnt,tot;
    void add(int x,int y){
       e[++tot].Next=head[x];
       e[tot].to=y;
       head[x]=tot;
    }
    void dfs1(int u,int f,int depth){
       d[u]=depth;
       fa[u]=f;
       siz[u]=1;
       for (int i=head[u];i;i=e[i].Next){
         int v=e[i].to;
         if (v==f)
            continue;
         dfs1(v,u,depth+1);
         siz[u]+=siz[v];
         if (siz[v]>siz[son[u]])
            son[u]=v;
       }
    }
    void dfs2(int u,int t){
        top[u]=t;
        id[u]=++cnt;
        if (!son[u])
            return;
        dfs2(son[u],t);
        for (int i=head[u];i;i=e[i].Next)
        {
            int v=e[i].to;
            if (v!=son[u] && v!=fa[u])
                dfs2(v,v);
        }
    }
    void push_down(int rt){
        if (tree[rt].laze){
           tree[lson].sum+=(tree[lson].r-tree[lson].l+1)*tree[rt].laze;
           tree[rson].sum+=(tree[rson].r-tree[rson].l+1)*tree[rt].laze;
           tree[lson].maxx+=tree[rt].laze;
           tree[rson].maxx+=tree[rt].laze;
           tree[lson].laze+=tree[rt].laze;
           tree[rson].laze+=tree[rt].laze;
           tree[rt].laze=0;
        }
    }
    void buildtree(int rt,int l,int r){
        tree[rt].l=l;
        tree[rt].r=r;
        tree[rt].sum=0;
        tree[rt].laze=0;
        tree[rt].maxx=0;
        int mid=(l+r)>>1;
        if (l==r){
            return;
        }
        buildtree(lson,l,mid);
        buildtree(rson,mid+1,r);
    }
    void update(int rt,int ul,int ur,int w){
       if (ul>ur)return;
       int l=tree[rt].l;
       int r=tree[rt].r;
       if (ul<=l && r<=ur){
         tree[rt].laze+=w;
         tree[rt].maxx+=w;
         tree[rt].sum+=(r-l+1)*w;
         return;
       }
       push_down(rt);
       int mid=(l+r)>>1;
       if (ur<=mid){
         update(lson,ul,ur,w);
       }else if (ul>mid){
         update(rson,ul,ur,w);
       }else {
         update(lson,ul,ur,w);
         update(rson,ul,ur,w);
       }
       tree[rt].maxx=max(tree[lson].maxx,tree[rson].maxx);
       tree[rt].sum=tree[lson].sum+tree[rson].sum;
    }
    void qRange(int x,int y,int k){
        while(top[x]!=top[y]){
            if (d[top[x]]<d[top[y]])swap(x,y);
            update(1,id[top[x]],id[x],k);
            x=fa[top[x]];
        }
        if (d[x]>d[y])swap(x,y);
        update(1,id[x],id[y],k);
    }
    int query(int rt,int ql,int qr,int w){
        int l=tree[rt].l;
        int r=tree[rt].r;
        if (tree[rt].sum==w*(r-l+1)){
            return r-l+1;
        }
        if (l==r){
            return 0;
        }
        push_down(rt);
        int mid=(l+r)>>1;
        int ans=0;
        if (tree[lson].maxx==w){
           ans+=query(lson,ql,qr,w);
        }
        if (tree[rson].maxx==w){
            ans+=query(rson,ql,qr,w);
        }
        return ans;
    }
    int main(){
      int t;
      scanf("%d",&t);
      int n;
      int ca=0;
      while(t--){
         memset(head,0,sizeof(head));
         memset(id,0,sizeof(id));
         memset(top,0,sizeof(top));
         memset(siz,0,sizeof(siz));
         memset(fa,0,sizeof(fa));
         memset(son,0,sizeof(son));
         memset(d,0,sizeof(d));
         scanf("%d",&n);
         cnt=0;
         tot=0;
         int u,v;
         for (int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
         }
         int r,op,k;
         dfs1(1,0,1);
         dfs2(1,1);
         scanf("%d",&op);
         printf("Case %d:
    ",++ca);
         buildtree(1,1,n);
         for (int i=1;i<=op;i++){
           scanf("%d",&k);
           for (int i=1;i<=k;i++){
              scanf("%d%d",&uu[i],&vv[i]);
              qRange(uu[i],vv[i],1);
           }
           int ans=query(1,1,n,k);
           for (int i=1;i<=k;i++){
              qRange(uu[i],vv[i],-1);
           }
           printf("%d
    ",ans);
         }
      }
      return 0;
    }
  • 相关阅读:
    oracle 10g 免安装客户端在windows下配置
    sql2005 sa密码
    使用windows live writer 有感
    windows xp SNMP安装包提取
    汉化groove2007
    迁移SQL server 2005 Reporting Services到SQL server 2008 Reporting Services全程截图操作指南
    foxmail 6在使用中的问题
    AGPM客户端连接不上服务器解决一例
    SpringSource Tool Suite add CloudFoundry service
    Java 之 SWing
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11567662.html
Copyright © 2011-2022 走看看