zoukankan      html  css  js  c++  java
  • UOJ#58. 【WC2013】糖果公园

    传送门

    分析

    首先先推荐一篇关于莫队的博客

    这个题我们不难看出就是树上带修莫队

    一直在犯sb错误,调了好长时间嘤嘤嘤

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    #define li long long
    const int LOG = 20;
    int n,m,q,val[100100],w[100100],now[100100],t1,t2,belong[300100];
    li ans[100100],Ans;
    int pr[100100][23],N,dfn[300100],beg[300100],fin[300100],dep[100100];
    int sum[100100],vis[100100],L,R,T;
    vector<int>v[100100];
    struct node {
        int x,y,t,ano,pl;
    };
    node d[100100];
    struct iint {
        int x,y,la;
    };
    iint a[100100];
    inline void dfs(int x,int fa){
        dep[x]=dep[fa]+1;
        for(int i=0;i<v[x].size();++i)
          if(v[x][i]!=fa){
            pr[v[x][i]][0]=x;
            dfs(v[x][i],x);
          }
    }
    inline void dfs2(int x,int fa){
        dfn[++N]=x;
        for(int i=0;i<v[x].size();++i)
          if(v[x][i]!=fa)dfs2(v[x][i],x);
        dfn[++N]=x;
    }
    inline int lca(int x,int y){
        if(dep[x]<dep[y])swap(x,y);
        for(int i=LOG;i>=0;--i)
          if(dep[pr[x][i]]>=dep[y])x=pr[x][i];
        if(x==y)return x;
        for(int i=LOG;i>=0;--i)
          if(pr[x][i]!=pr[y][i])
            x=pr[x][i],y=pr[y][i];
        return pr[x][0];
    }
    inline bool cmp(const node &x,const node &y){
        if(belong[x.x]==belong[y.x]){
          if(x.y==y.y)return x.t<y.t;
          return x.y<y.y;
        }
        return x.x<y.x;
    }
    inline void add(int x){
        sum[now[x]]++;
        Ans+=(li)w[sum[now[x]]]*val[now[x]];
    }
    inline void deal(int x){
        Ans-=(li)w[sum[now[x]]]*val[now[x]];
        sum[now[x]]--;
    }
    inline void go(int x,int k){
        int u=(k?x:dfn[x]);
        vis[u]^=1;
        if(vis[u])add(u);
          else deal(u);
    }
    inline void goago(int x){
        int u=a[x].x;
        if(vis[u])deal(u);
        now[u]=a[x].la;
        if(vis[u])add(u);
    }
    inline void gonxt(int x){
        int u=a[x].x;
        a[x].la=now[u];
        if(vis[u])deal(u);
        now[u]=a[x].y;
        if(vis[u])add(u);
    }
    inline int ra(){
        int x=0;char s=getchar();
        while(!isdigit(s))s=getchar();
        while(isdigit(s))x=(x<<3)+(x<<1)+(s-'0'),s=getchar();
        return x;
    }
    int main(){
        int i,j,k,x,y;
        n=ra(),m=ra(),q=ra();
        for(i=1;i<=m;++i)val[i]=ra();
        for(i=1;i<=n;++i)w[i]=ra();
        for(i=1;i<n;++i){
          x=ra(),y=ra();
          v[x].push_back(y);
          v[y].push_back(x);
        }
        for(i=1;i<=n;++i)now[i]=ra();
        for(i=1;i<=q;++i){
          k=ra(),x=ra(),y=ra();
          if(k){
              d[++t1].x=x;
              d[t1].y=y;
              d[t1].t=t2;
              d[t1].pl=t1;
          }else {
              a[++t2].x=x;
              a[t2].y=y;
          }
        }
        pr[1][0]=0;
        dfs(1,0);
        for(i=1;i<=LOG;++i)
          for(j=1;j<=n;++j)
            pr[j][i]=pr[pr[j][i-1]][i-1];
        dfs2(1,0);
        for(i=1;i<=N;++i)
          if(!beg[dfn[i]])beg[dfn[i]]=i;
        for(i=N;i>0;i--)
          if(!fin[dfn[i]])fin[dfn[i]]=i;
        for(i=1;i<=t1;++i){
          x=d[i].x,y=d[i].y;
          if(beg[x]>beg[y])swap(x,y);
          k=lca(x,y);
          if(x==k)d[i].x=min(fin[x],fin[y]),d[i].y=max(fin[y],fin[x]),d[i].ano=-1;
            else d[i].x=beg[x]+1,d[i].y=fin[y]-1,d[i].ano=k;
        }
        double block=pow((double)N,2.0/3);
        int B=block;
        for(i=1;i<=N;++i)
          belong[i]=(i-1)/B+1;
        sort(d+1,d+t1+1,cmp);
        L=1,R=0,T=0;
        for(i=1;i<=t1;++i){
          while(T>d[i].t){
              goago(T);
              T--;
          }
          while(T<d[i].t){
              T++;
              gonxt(T);
          }
          while(R>d[i].y){
              go(R,0);
              R--;
          }
          while(R<d[i].y){
              R++;
              go(R,0);
          }
          while(L>d[i].x){
              L--;
              go(L,0);
          }
          while(L<d[i].x){
              go(L,0);
              L++;
          }
          if(d[i].ano!=-1)go(d[i].ano,1);
          ans[d[i].pl]=Ans;
          if(d[i].ano!=-1)go(d[i].ano,1);
        }
        for(i=1;i<=t1;++i)
          printf("%lld
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    聊聊MySQL的索引吧
    污力满满的技术解读,瞬间印象深刻
    lua语言(1):安装、基本结构、函数、输入输出
    pandas中的那些让人有点懵逼的异常(坑向)
    与分布式相关的面试题
    图解IP基础知识
    Date类
    String 与StringBuffer习题
    Java的常用类 String
    线程练习题
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10390846.html
Copyright © 2011-2022 走看看