zoukankan      html  css  js  c++  java
  • bzoj 3052: [wc2013]糖果公园 带修改莫队

    3052: [wc2013]糖果公园

    Time Limit: 250 Sec  Memory Limit: 512 MB
    Submit: 506  Solved: 189
    [Submit][Status]

    Description

    Input

    Output

    Sample Input

    Sample Input

     

    Sample Output

    84
    131
    27
    84

    HINT

      本来这道题想到了莫队算法,但是看到带修改就直接放弃了。结果看题解才发现带修改居然也能用莫队!!!之所以可以这样用,是因为修改的时间复杂度非常非常低,以至于可以在修改的时间轴上任意跳跃。具体细节自己去看其他题解啦。

      写的有点长,但是跑的还算比较快。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define MAXN 100100
    #define MAXB 2200
    #define MAXQ 100100
    #define MAXV MAXN
    #define MAXE MAXV*2
    typedef long long qword;
    inline int nextInt()
    {
            register int x=0;
            register int ch;
            while (ch=getchar(),ch<'0' || ch>'9');
            while (x=x*10+ch-'0',ch=getchar(),ch<='9' && ch>='0');
            return x;
    }
    int n,m,q,sb;
    struct Edge
    {
            int np;
            Edge *next;
    }E[MAXE],*V[MAXV];
    int tope=-1;
    int que[MAXN];
    void addedge(int x,int y)
    {
            E[++tope].np=y;
            E[tope].next=V[x];
            V[x]=&E[tope];
    }
    int depth[MAXN];
    int pnt[MAXN];
    int top[MAXN],bsiz[MAXN];
    int belong[MAXN];
    int topb=0;
    void bfs1()
    {
            Edge *ne;
            int now;
            int head=-1,tail=0;
            que[0]=1;
            pnt[1]=1;
            belong[1]=++topb;
            top[1]=1;
            bsiz[1]=1;
            depth[1]=1;
            while (head<tail)
            {
                    now=que[++head];
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (ne->np==pnt[now])continue;
                            que[++tail]=ne->np;
                            pnt[ne->np]=now;
                            depth[ne->np]=depth[now]+1;
                            if (bsiz[belong[now]]<sb)
                            {
                                    bsiz[belong[now]]++;
                                    belong[ne->np]=belong[now];
                                    top[ne->np]=top[now];
                            }else
                            {
                                    belong[ne->np]=++topb;
                                    bsiz[topb]=1;
                                    top[ne->np]=ne->np;
                            }
                    }
            }
    }
    int jump[20][MAXN];
    void init_lca()
    {
            for (int i=1;i<=n;i++)
                    jump[0][i]=pnt[i];
            for (int j=1;j<20;j++)
                    for (int i=1;i<=n;i++)
                            jump[j][i]=jump[j-1][jump[j-1][i]];
    }
    int lca(int x,int y)
    {
            if (depth[x]<depth[y])swap(x,y);
            int dep=depth[x]-depth[y];
            for (int i=0;i<20;i++)
                    if (dep & (1<<i))
                            x=jump[i][x];
            if (x==y)return x;
            for (int i=19;i>=0;i--)
                    if (jump[i][x]!=jump[i][y])
                            x=jump[i][x],y=jump[i][y];
            return pnt[x];
    }
    int get_dis(int x,int y)
    {
            return depth[x]+depth[y]-2*depth[lca(x,y)];
    }
    struct qur_t
    {
            int s,t,id;
            int upper_pos;
            qword ans;
    }qur[MAXQ];
    int topq=-1;
    bool cmp_qur_block(qur_t a1,qur_t a2)
    {
            if (belong[a1.s]!=belong[a2.s])
                    return belong[a1.s]<belong[a2.s];
            if (belong[a1.t]!=belong[a2.t])
                    return belong[a1.t]<belong[a2.t];
            return a1.id<a2.id;
    }
    bool cmp_qur_id(qur_t a1,qur_t a2)
    {
            return a1.id<a2.id;
    }
    int sweet[MAXN];
    qword suprise[MAXN];
    int candy[MAXN];
    struct mdfy_t
    {
            int pos,cnew,cold,id;
    }mdfy[MAXN];
    int topm=-1;
    struct path
    {
            int s,t,a,ds;
            path(int s,int t):s(s),t(t)
            {
                    a=lca(s,t);
                    ds=depth[s]+depth[t]-2*depth[a];
            }
            path(){}
            bool inside(int x)
            {
                    return get_dis(x,s)+get_dis(x,t)==ds;
            }
            void get_path(int *step,int &tops)
            {
                    tops=-1;
                    for (int x=s;x!=a;x=pnt[x])
                            step[++tops]=x;
                    tops=ds;
                    for (int x=t;x!=a;x=pnt[x])
                            step[tops--]=x;
                    step[tops--]=a;
                    tops=ds;
            }
    };
    int tot[MAXN];
    bool inside[MAXN];
    int step[MAXN],tops;
    int main()
    {
        //    freopen("input.txt","r",stdin);
        //    freopen("output.txt","w",stdout);
            int x,y,z;
            n=nextInt(),m=nextInt(),q=nextInt();
            sb=pow(n,2.0/3);
            for (int i=1;i<=m;i++)
                    sweet[i]=nextInt();
            for (int i=1;i<=n;i++)
                    suprise[i]=nextInt();
            for (int i=1;i<=n;i++)suprise[i]+=suprise[i-1];
            for (int i=1;i<n;i++)
            {
                    x=nextInt(),y=nextInt();
                    addedge(x,y);
                    addedge(y,x);
            }
            for (int i=1;i<=n;i++)
                    candy[i]=nextInt();
            int opt;
            for (int i=1;i<=q;i++)
            {
                    opt=nextInt();
                    if (opt==0)
                    {
                            x=nextInt(),y=nextInt();
                            ++topm;
                            mdfy[topm].pos=x;
                            mdfy[topm].cnew=y;
                            mdfy[topm].cold=candy[x];
                            candy[x]=y;
                            mdfy[topm].id=i;
                    }else
                    {
                            x=nextInt(),y=nextInt();
                            ++topq;
                            qur[topq].s=x;
                            qur[topq].t=y;
                            qur[topq].upper_pos=topm+1;
                            qur[topq].id=i;
                    }
            }
            for (int i=topm;i>=0;i--)
                    candy[mdfy[i].pos]=mdfy[i].cold;
            bfs1();
            init_lca();
            sort(qur,qur+topq+1,cmp_qur_block);
            for (int i=0;i<qur[0].upper_pos;i++)
                    candy[mdfy[i].pos]=mdfy[i].cnew;
            int a;
            a=lca(qur[0].s,qur[0].t);
            qword nsum=0;
            for (x=qur[0].s;x!=a;x=pnt[x])
            {
                    inside[x]=true;
                    tot[candy[x]]++;
                    nsum+=(suprise[tot[candy[x]]]-suprise[tot[candy[x]]-1])*sweet[candy[x]];
            }
            for (y=qur[0].t;;y=pnt[y])
            {
                    inside[y]=true;
                    tot[candy[y]]++;
                    nsum+=(suprise[tot[candy[y]]]-suprise[tot[candy[y]]-1])*sweet[candy[y]];
                    if (y==a)break;
            }
            qur[0].ans=nsum;
            path pnow(qur[0].s,qur[0].t);
            path pwalk;
            for (int i=1;i<=topq;i++)
            {
                    for (int kk=0;kk<2;kk++)
                    {
                            if (kk==0)
                                    pwalk=path(qur[i-1].s,qur[i].s);
                            else
                                    pwalk=path(qur[i-1].t,qur[i].t);
                            pwalk.get_path(step,tops);
                            bool flag=true;
                            for (int j=0;j<=tops+1;j++)
                            {
                                    if (j!=tops+1 && inside[step[j]])
                                    {
                                            inside[step[j]]=false;
                                            tot[candy[step[j]]]--;
                                            nsum+=(suprise[tot[candy[step[j]]]]-suprise[tot[candy[step[j]]]+1])*sweet[candy[step[j]]];
                                    }else
                                    {
                                            if (flag)
                                            {
                                                    inside[step[j-1]]=true;
                                                    tot[candy[step[j-1]]]++;
                                                    nsum+=(suprise[tot[candy[step[j-1]]]]-suprise[tot[candy[step[j-1]]]-1])*sweet[candy[step[j-1]]];
                                                    flag=false;
                                            }
                                            if (j==tops+1)break;
                                            inside[step[j]]=true;
                                            tot[candy[step[j]]]++;
                                            nsum+=(suprise[tot[candy[step[j]]]]-suprise[tot[candy[step[j]]]-1])*sweet[candy[step[j]]];
                                    }
                            }
                    }
                    if (qur[i-1].upper_pos<qur[i].upper_pos)
                    {
                            for (int j=qur[i-1].upper_pos;j<qur[i].upper_pos;j++)
                            {
                                    if (candy[mdfy[j].pos]!=mdfy[j].cold)throw;
                                    candy[mdfy[j].pos]=mdfy[j].cnew;
                                    if (inside[mdfy[j].pos])
                                    {
                                            tot[mdfy[j].cold]--;
                                            nsum+=(suprise[tot[mdfy[j].cold]]-suprise[tot[mdfy[j].cold]+1])*sweet[mdfy[j].cold];
                                            tot[mdfy[j].cnew]++;
                                            nsum+=(suprise[tot[mdfy[j].cnew]]-suprise[tot[mdfy[j].cnew]-1])*sweet[mdfy[j].cnew];
                                    }
                            }
                    }else
                    {
                            for (int j=qur[i-1].upper_pos-1;j>=qur[i].upper_pos;j--)
                            {
                                    if (candy[mdfy[j].pos]!=mdfy[j].cnew)throw;
                                    candy[mdfy[j].pos]=mdfy[j].cold;
                                    if (inside[mdfy[j].pos])
                                    {
                                            tot[mdfy[j].cnew]--;
                                            nsum+=(suprise[tot[mdfy[j].cnew]]-suprise[tot[mdfy[j].cnew]+1])*sweet[mdfy[j].cnew];
                                            tot[mdfy[j].cold]++;
                                            nsum+=(suprise[tot[mdfy[j].cold]]-suprise[tot[mdfy[j].cold]-1])*sweet[mdfy[j].cold];
                                    }
                            }
                    }
                    qur[i].ans=nsum;
            }
            sort(qur,qur+topq+1,cmp_qur_id);
            for (int i=0;i<=topq;i++)
                    printf("%lld
    ",qur[i].ans);
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    WRF WPS预处理
    CVS安装
    Linux窗口最小化消失,任务栏上无法找到的解决方法
    NCARG安装配置出现error while loading shared libraries: libg2c.so.0问题额解决办法
    Netcdf安装
    Embedding R-generated Interactive HTML pages in MS PowerPoint(转)
    The leaflet package for online mapping in R(转)
    Some 3D Graphics (rgl) for Classification with Splines and Logistic Regression (from The Elements of Statistical Learning)(转)
    What does a Bayes factor feel like?(转)
    Weka算法介绍
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4304353.html
Copyright © 2011-2022 走看看