zoukankan      html  css  js  c++  java
  • SPOJ QTREE4 Query on a tree IV ——动态点分治

    【题目分析】

        同bzoj1095

        然后WA掉了。

        发现有负权边,只好把rmq的方式改掉。

        然后T了。

        需要进行底(ka)层(chang)优(shu)化。

        然后还是T

        下午又交就A了。

    【代码】

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define maxe 200005
    #define maxn 100005
    #define inf (0x3f3f3f3f)
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    int h[maxe],to[maxe],ne[maxe],en=0,ban[maxn],n,m,rt,now,dst[maxn],Tree_rt,col[maxn],ans=-1,x,aim;
    int b[maxn<<2],cnt=0,tag=0,pos[maxn],c[maxn<<2][20],_log[maxn<<2],w[maxe],d[maxn<<2][20],dep[maxn];
     
    void add(int a,int b,int c) {to[en]=b;ne[en]=h[a];w[en]=c;h[a]=en++;}
    struct Heap{
        priority_queue <int> heap,del;
        void Ins(int x){heap.push(x);}
        void Del(int x){del.push(x);}
        void Pop(){while (del.size()&&del.top()==heap.top()) del.pop(),heap.pop(); heap.pop();}
        int Top(){while (del.size()&&del.top()==heap.top()) del.pop(),heap.pop(); return heap.top();}
        int S_Top(){int tmp=Top(),ret;Pop();ret=Top();Ins(tmp);return ret;  }
        int Size(){return heap.size()-del.size();}
    }s1[maxn],s2[maxn],lst;
     
    int mx[maxn],siz[maxn],size,fa[maxn];
    char opt[11];
     
    void dfs(int o,int fa)
    {
        if (!tag)b[++cnt]=o,pos[o]=cnt;
        siz[o]=1;mx[o]=0;
        for (int i=h[o];i>=0;i=ne[i])
            if (!ban[to[i]]&&to[i]!=fa)
            {
            	if (!tag) dep[to[i]]=dep[o]+1;
                dfs(to[i],o);
                if (!tag) b[++cnt]=o;
                siz[o]+=siz[to[i]];
                if (siz[to[i]]>mx[o]) mx[o]=siz[to[i]];  
            }
    }
     
    void dfs_rt(int o,int fa)
    {
        if (max(mx[o],size-siz[o])<now) rt=o,now=max(mx[o],size-siz[o]);
        for (int i=h[o];i>=0;i=ne[i])
            if (!ban[to[i]]&&to[i]!=fa) dfs_rt(to[i],o);
    }
     
    int lca(int a,int b)
    {
        int pa=pos[a],pb=pos[b];
        if (pa>pb) swap(pa,pb);
        int l=_log[pb-pa+1];
        if (dep[d[pa][l]]<dep[d[pb-(1<<l)+1][l]]) return dst[d[pa][l]];
        else return dst[d[pb-(1<<l)+1][l]];
    }
     
    int dist(int a,int b)
    {
    	if (a==0) a=Tree_rt;
    	if (b==0) b=Tree_rt;
    	return dst[a]+dst[b]-2*lca(a,b);
    }
     
    void dfs_add(int o,int fa)
    {
        s1[rt].Ins((dist(o,aim)));
        for (int i=h[o];i>=0;i=ne[i])
            if (!ban[to[i]]&&to[i]!=fa)
                dfs_add(to[i],o);
    }
     
    void Divide(int o,int fat)
    {
        int root; 
        dfs(o,-1); size=siz[o]; now=inf;
        dfs_rt(o,-1); root=rt;
        if (fat) fa[root]=fat;
        ban[root]=1;
        aim=fat;
        dfs_add(root,-1);
        s2[fat].Ins(s1[root].Top());
        if (!col[root]) s2[root].Ins(0);
        for (int i=h[root];i>=0;i=ne[i])
            if (!ban[to[i]]) Divide(to[i],root);
        if (s2[root].Size()>=2)
        {
        	int tmp=s2[root].Top()+s2[root].S_Top();
            lst.Ins(tmp);
        }
    }
     
    void dfs_dist(int o,int fat)
    {
        for (int i=h[o];i>=0;i=ne[i])
        if (to[i]!=fat) dst[to[i]]=dst[o]+w[i],dfs_dist(to[i],o);
    }
     
    void Delete(int o)
    {
        if (s2[o].Size()>=2) lst.Del(s2[o].Top()+s2[o].S_Top());
        s2[o].Del(0);
        if (s2[o].Size()>=2)
        {
        	int tmp=s2[o].Top()+s2[o].S_Top(); lst.Ins(tmp);
        }
        if (s2[o].Size()>0) ans=max(ans,0);
        int now=o;
        while (now)
        {
            int fat=fa[now];
            if (s2[fat].Size()>=2)lst.Del(s2[fat].Top()+s2[fat].S_Top());
            int tmp=s1[now].Top();
            s1[now].Del(dist(o,fat));
            if (s1[now].Size()==0||tmp!=s1[now].Top())
            {
                s2[fat].Del(tmp);
                if (s1[now].Size()>0) s2[fat].Ins(s1[now].Top());
            }
            if (s2[fat].Size()>=2)
            {
            	int tmp=s2[fat].Top()+s2[fat].S_Top();
                lst.Ins(tmp);
            }
            if (s2[fat].Size()>0) ans=max(ans,0);
            now=fat;
        }
    }
     
    void Insert(int o)
    {
        if (s2[o].Size()>=2)
        {
            lst.Del(s2[o].Top()+s2[o].S_Top());
        }
        s2[o].Ins(0);
        if (s2[o].Size()>=2)
        {
        	int tmp=s2[o].Top()+s2[o].S_Top();lst.Ins(tmp);
        }
        if (s2[o].Size()>0) ans=max(ans,0);
        int now=o;
        while (now)
        {
            int fat=fa[now];
            if (s2[fat].Size()>=2) lst.Del(s2[fat].Top()+s2[fat].S_Top());
            int tmp,flag=0;
            if (s1[now].Size()==0) flag=1;
            else tmp=s1[now].Top();
            s1[now].Ins(dist(o,fat));
            if (flag||tmp!=s1[now].Top())
            {
                if (!flag) s2[fat].Del(tmp);
                s2[fat].Ins(s1[now].Top());
            }
            if (s2[fat].Size()>=2)
            {
            	int tmp=s2[fat].Top()+s2[fat].S_Top();
                lst.Ins(tmp);
            }
            if (s2[fat].Size()>0) ans=max(ans,0);
            now=fat;
        }
    }
    
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
     
    int main()
    {
        memset(h,-1,sizeof h);
    	n=Getint();
        F(i,1,n-1)
        {
            int a,b,c;
    		a=Getint();b=Getint();c=Getint();
            add(a,b,c);add(b,a,c);
        }
        tag=1;
        dfs(1,-1);
        now=inf; size=siz[1]; dfs_rt(1,-1); dfs_dist(rt,-1);
        tag=0;
        dfs(rt,-1);
        tag=1;
    	F(i,2,cnt) _log[i]=_log[i>>1]+1;
    	F(i,1,cnt) d[i][0]=b[i];
        F(j,1,_log[cnt])
            for (int i=1;i+(1<<j)-1<=cnt;++i)
            {
            	if (dep[d[i][j-1]]<dep[d[i+(1<<j-1)][j-1]]) d[i][j]=d[i][j-1];
            	else d[i][j]=d[i+(1<<j-1)][j-1];
    		}
        Tree_rt=rt;
        Divide(1,0);
        scanf("%d",&m);
        F(i,1,m)
        {
            scanf("%s",opt);
            switch(opt[0])
            {
                case 'A': if (lst.Size()) ans=max(ans,lst.Top());printf("%d
    ",ans); break;
                case 'C': x=Getint();ans=-1; if (!col[x]) Delete(x); else Insert(x); col[x]^=1; break;
            }
        }
    }
    

      

  • 相关阅读:
    AC自动机
    HDU
    2020牛客寒假算法基础集训营3 B 牛牛的DRB迷宫II
    POJ 3784 Running Median【维护动态中位数】
    CodeForces
    HDU 2444 The Accomodation of Students【二分图最大匹配问题】
    POJ 1201 Intervals【差分约束】
    POJ 2976 Dropping tests【0/1分数规划模板】
    2019牛客暑期多校训练营(第七场)A.String【最小表示法】
    POJ 1287 Networking【kruskal模板题】
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6413787.html
Copyright © 2011-2022 走看看