zoukankan      html  css  js  c++  java
  • bzoj4012[HNOI2015]开店

    http://www.lydsy.com/JudgeOnline/problem.php?id=4012

    动态树分治。

    做过上一题捉迷藏,对动态树分治有了更深的认识。

    ”所有顶点的度数都小于或等于3“,好强的暗示。

    类似的做法,先求重心,对于与重心相连的每棵子树,求出到每棵子树中所有点到重心的距离。每棵子树中的点按年龄排序,并求距离的前缀和。

    然后递归即可。

    对于询问,因为每个点最多“属于”$logn$个重心,在这$logn$个重心所对应的树中二分即可。

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<fstream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<utility>
    #include<set>
    #include<bitset>
    #include<vector>
    #include<functional>
    #include<deque>
    #include<cctype>
    #include<climits>
    #include<complex>
    //#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
     
    using namespace std;
    
    typedef long long LL;
    typedef double DB;
    typedef pair<int,int> PII;
    typedef complex<DB> CP;
    
    #define mmst(a,v) memset(a,v,sizeof(a))
    #define mmcy(a,b) memcpy(a,b,sizeof(a))
    #define fill(a,l,r,v) fill(a+l,a+r+1,v)
    #define re(i,a,b)  for(i=(a);i<=(b);i++)
    #define red(i,a,b) for(i=(a);i>=(b);i--)
    #define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
    #define fi first
    #define se second
    #define m_p(a,b) make_pair(a,b)
    #define p_b(a) push_back(a)
    #define SF scanf
    #define PF printf
    #define two(k) (1<<(k))
    
    template<class T>inline T sqr(T x){return x*x;}
    template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
    template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}
    
    inline int sgn(DB x){if(abs(x)<1e-9)return 0;return(x>0)?1:-1;}
    const DB Pi=acos(-1.0);
    
    int gint()
      {
            int res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    LL gll()
      {
          LL res=0;bool neg=0;char z;
            for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
            if(z==EOF)return 0;
            if(z=='-'){neg=1;z=getchar();}
            for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
            return (neg)?-res:res; 
        }
    
    const int maxn=150000;
    
    int n,Q,A;
    int age[maxn+100];
    int now[2],info[2][maxn+100];
    struct Tedge{int v,cost,next,kind;}edge[2][maxn*20];
    
    void addedge(int k,int u,int v,int cost,int kind=0)
      {
          edge[k][++now[k]]=k?(Tedge){v,cost,info[k][u],kind}:(Tedge){v,cost,info[k][u],0};
          info[k][u]=now[k];
      }
    
    struct Tdata
      {
          int age,dist;LL sum;
          Tdata(int _age=0,int _dist=0){age=_age;dist=_dist;sum=0;}
          friend bool const operator <(const Tdata a,const Tdata b){return a.age<b.age;}
      };
    
    int num;
    int mark[maxn+100],gen[maxn+100],degree[maxn+100];
    vector<Tdata> S[maxn+100][4];
    
    int sz[maxn+100],mx[maxn+100];
    void getrt(int u,int fa,int all,int &rt)
      {
          int i,v;
          sz[u]=1;mx[u]=0;
          for(i=info[0][u],v=edge[0][i].v;i!=-1;i=edge[0][i].next,v=edge[0][i].v)if(!mark[v] && v!=fa)getrt(v,u,all,rt),sz[u]+=sz[v],upmax(mx[u],sz[v]);
          upmax(mx[u],all-sz[u]);
          if(!rt || mx[u]<mx[rt])rt=u;
      }
    void dfs(int u,int fa,int dist,int cur,int kind)
      {
          S[cur][kind].p_b(Tdata(age[u],dist));
          addedge(1,u,cur,dist,kind);
          int i,v,cost;
          for(i=info[0][u],v=edge[0][i].v,cost=edge[0][i].cost;i!=-1;i=edge[0][i].next,v=edge[0][i].v,cost=edge[0][i].cost)if(!mark[v] && v!=fa)dfs(v,u,dist+cost,cur,kind);
      }
    void prep(int u,int all)
      {
          if(all<=1)return;
          int i,j,rt=0,tmp=0;
          getrt(u,-1,all,rt);
          getrt(rt,-1,all,tmp);
          int cur=++num,v,cost;
            mark[rt]=cur;gen[cur]=rt;degree[cur]=0;
            addedge(1,rt,cur,0,0);
          for(i=info[0][rt],v=edge[0][i].v,cost=edge[0][i].cost;i!=-1;i=edge[0][i].next,v=edge[0][i].v,cost=edge[0][i].cost)if(!mark[v])
            {
                int t=++degree[cur];
              dfs(v,rt,cost,cur,t);
              sort(S[cur][t].begin(),S[cur][t].end());
              S[cur][t][0].sum=S[cur][t][0].dist;re(j,1,int(S[cur][t].size())-1)S[cur][t][j].sum=S[cur][t][j-1].sum+S[cur][t][j].dist;
              prep(v,sz[v]);
            }
      }
    LL ask(int x,int M)
      {
          int i,j,cur,dis,kind;LL res=0;
          for(i=info[1][x],cur=edge[1][i].v,dis=edge[1][i].cost,kind=edge[1][i].kind;i!=-1;i=edge[1][i].next,cur=edge[1][i].v,dis=edge[1][i].cost,kind=edge[1][i].kind)
            {
                if(age[gen[cur]]<=M)res+=dis;
              re(j,1,degree[cur])if(j!=kind)
                {
                    vector<Tdata>::iterator it=upper_bound(S[cur][j].begin(),S[cur][j].end(),Tdata(M));
                    if(it==S[cur][j].begin())continue;
                    it--;
                    res+=it->sum+1LL*(it-S[cur][j].begin()+1)*dis;
                }
            }
          return res;
      }
                  
    int main()
      {
          freopen("bzoj4012.in","r",stdin);
          freopen("bzoj4012.out","w",stdout);
          int i;
          n=gint();Q=gint();A=gint();
          re(i,1,n)age[i]=gint();
          mmst(now,-1);mmst(info,-1);
          re(i,1,n-1){int u=gint(),v=gint(),cost=gint();addedge(0,u,v,cost);addedge(0,v,u,cost);}
          prep(1,n);
          LL lastans=0;
          while(Q--)
            {
                int x=gint(),a=gint(),b=gint(),L=(LL(a)+lastans)%LL(A),R=(LL(b)+lastans)%LL(A);
                if(L>R)swap(L,R);
                lastans=ask(x,R)-ask(x,L-1);
                PF("%I64d
    ",lastans);
            }
          return 0;
      }
    View Code
  • 相关阅读:
    实战演练:通过伪列、虚拟列实现SQL优化
    python try else
    Prince2是怎么考试的?
    Prince2是怎么考试的?
    Prince2是怎么考试的?
    Prince2是怎么考试的?
    拦截器
    拦截器
    拦截器
    拦截器
  • 原文地址:https://www.cnblogs.com/maijing/p/4984758.html
Copyright © 2011-2022 走看看