zoukankan      html  css  js  c++  java
  • BZOJ -3730(动态点分治)

    题目:在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]。
    不幸的是,这片土地常常发生地震,并且随着时代的发展,城市的价值也往往会发生变动。
    接下来你需要在线处理M次操作:
    0 x k 表示发生了一次地震,震中城市为x,影响范围为k,所有与x距离不超过k的城市都将受到影响,该次地震造成的经济损失为所有受影响城市的价值和。
    1 x y 表示第x个城市的价值变成了y。
    为了体现程序的在线性,操作中的x、y、k都需要异或你程序上一次的输出来解密,如果之前没有输出,则默认上一次的输出为0。

    思路:点分树,动态维护一个重心的信息。 这里维护的是点到其他点的某距离下的权值和。 注意处理重复信息。

    时间卡得有点紧,ST表求LCA,没树剖快。。。居然?

    线段树没树状数组快,这个可以理解,关键是在于怎么开点,不会炸空间--------把空间和点分树的对应起来O(NlogN)就可以了。

    (T了很多次,也改(抄)了不少写法,日后再来补。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 111111
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int n,m,V[MAX];
    struct Line{int v,next;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    /********************************************************************/
    /*int size[MAX],dfn[MAX],top[MAX],dep[MAX],fa[MAX],tim,hson[MAX];
    void dfs1(int u,int ff)
    {
        fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1;
        for(int i=h[u];i;i=e[i].next)
        {
            int v=e[i].v;if(v==ff)continue;
            dfs1(v,u);size[u]+=size[v];
            if(size[v]>size[hson[u]])hson[u]=v;
        }
    }
    void dfs2(int u,int tp)
    {
        top[u]=tp;
        if(hson[u])dfs2(hson[u],tp);
        for(int i=h[u];i;i=e[i].next)
            if(e[i].v!=fa[u]&&e[i].v!=hson[u])
                dfs2(e[i].v,e[i].v);
    }
    int LCA(int u,int v)
    {
        while(top[u]^top[v])dep[top[u]]<dep[top[v]]?v=fa[top[v]]:u=fa[top[u]];
        return dep[u]<dep[v]?u:v;
    }
    int Dis(int u,int v){return dep[u]+dep[v]-2*dep[LCA(u,v)];}*/
    bool vis[MAX];
    int ver[MAX<<1],first[MAX<<1],dept[MAX<<1],Tot;
    int dp[MAX<<1][21],dep[MAX<<1];
    void dfs(int u ,int d)
    {
        vis[u]=true;
        ver[++Tot] = u;
        first[u] = Tot;
        dept[Tot] = d; dep[u]=d;
       for(int i=h[u];i;i=e[i].next)
            if( !vis[e[i].v] )
            {
                dfs(e[i].v,d+1);
                ver[++Tot] = u;
                dept[Tot] = d;
            }
    }
    
    void ST(int N)
    {
        for(int i=1;i<=N;i++)  dp[i][0] = i;
        for(int j=1;(1<<j)<=N;j++)
        {
            for(int i=1;i+(1<<j)-1<=N;i++)
            {
                int a = dp[i][j-1] , b = dp[i+(1<<(j-1))][j-1];
                dp[i][j] = dept[a]<dept[b]?a:b;
            }
        }
    }
    int lg2[MAX<<1];
    int RMQ(int l,int r)
    {
        int k=0;
        //while((1<<(k+1))<=r-l+1)  k++;
        k=lg2[r-l+1];
        int a=dp[l][k],b=dp[r-(1<<k)+1][k];
        return dept[a]<dept[b]?a:b;
    }
    
    int LCA(int u ,int v)
    {
        int x = first[u] , y = first[v];
        int res;
        if(x<=y) res = RMQ(x,y);
        else res=RMQ(y,x);
        //cout<<u<<" "<<v<<" : "<<ver[res]<<endl;
        return ver[res];
    }
    int Dis(int u,int v)
    {
        return dep[u]+dep[v]-(dep[LCA(u,v)]<<1);
    }
    namespace BIT{
        typedef vector<int> vec;
        struct BIT{
            vec tree; int n;
            inline void init(int size) {tree.resize(size+2); n=size+1;}
            inline int lowbit(int x) {return x&-x;}
            inline void Modify(int x,int d) {if (x<=0) return; for (int i=x; i<=n; i+=lowbit(i)) tree[i]+=d;}
            inline int Query(int x) {int re=0; if (x>n) x=n; for (int i=x; i>0; i-=lowbit(i)) re+=tree[i]; return re;}
        }G[MAX<<1];
    }using namespace BIT;
    int Fa[MAX],Size,root,mx,size[MAX];
    void Getroot(int u,int ff)
    {
        size[u]=1;int ret=0;
        for(int i=h[u];i;i=e[i].next)
        {
            int v=e[i].v;if(v==ff||vis[v])continue;
            Getroot(v,u);size[u]+=size[v];
            ret=max(ret,size[v]);
        }
        ret=max(ret,Size-size[u]);
        if(ret<mx)mx=ret,root=u;
    }
    void DFS(int u,int ff)
    {
        vis[u]=true;Fa[u]=ff;
        for(int i=h[u];i;i=e[i].next)
        {
            int v=e[i].v;if(vis[v])continue;
            mx=Size=size[v];
            Getroot(v,u);
            G[root].init(Size); G[root+n].init(Size);
            DFS(root,u);
        }
    }
    void Modify(int x,int w)
    {
        G[x].Modify(1,w);
        for(int i=x;Fa[i];i=Fa[i])
        {
            int dis=Dis(x,Fa[i]);
            G[Fa[i]].Modify(dis+1,w);
            G[i+n].Modify(dis+1,w);
        }
    }
    int Query(int x,int K)
    {
        int ret=G[x].Query(K+1);
        for(int i=x;Fa[i];i=Fa[i])
        {
            int dis=Dis(x,Fa[i]);if(dis>K)continue;
            //ret+=Query(rt[Fa[i]],0,n,0,K-dis);
            //ret-=Query(rt[i+n],0,n,0,K-dis);
            ret+=G[Fa[i]].Query(K-dis+1);
            ret-=G[i+n].Query(K-dis+1);
        }
        return ret;
    }
    /********************************************************************/
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;++i)V[i]=read();
        for(int i=1;i<n;++i)
        {
            int u=read(),v=read();
            Add(u,v);Add(v,u);
        }
        /*dfs1(1,0);dfs2(1,1);*/
        dfs(1,0);
        ST(Tot);
        lg2[0]=-1;
        for(int i=1;i<=Tot;i++) lg2[i]=lg2[i>>1]+1;
        for(int i=1;i<=n;i++) vis[i]=0;
        Size=mx=n;
        Getroot(1,0); G[root].init(n); G[root+n].init(n);DFS(root,0);
        for(int i=1;i<=n;++i) Modify(i,V[i]);
        int ans=0;
        while(m--)
        {
            int opt=read(),x=read()^ans,y=read()^ans;
            if(opt==0)printf("%d
    ",ans=Query(x,y));
            else Modify(x,y-V[x]),V[x]=y;
        }
        return 0;
    }
  • 相关阅读:
    如何同步共享同一个list
    Java多线程生产者消费者模式(一)之两个线程交替执行
    Java多线程之如何在线程间共享数据
    Java多线程(四)实现多线程的三种方法之JUC的Callable接口
    Java线程的6种状态
    Java lambda表达式的进化论
    Java内部类
    Java多线程(五)锁机制之synchronized 同步方法和同步块
    Java装饰者模式
    Java多线程(三)实现多线程的三种方法之Runnable接口
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11175091.html
Copyright © 2011-2022 走看看