Query on a graph HDU - 5957

http://acm.hdu.edu.cn/showproblem.php?pid=5957

好想但是难写

先求个生成树 并把多余边记下来 跑个bfs序并用线段树维护

bfs序和dfs序略有不同 对一个节点 遍历一遍其所有子节点并取最小最大值会得到其一级子节点在bfs序中的区间 再跑一遍就会得到二级子节点在bfs序中的区间 依此类推

然后就是恶心的分类讨论 写了一屏都没写完。。索性把所有要操作的区间都存下来 排个序去个重就好了

 

#include 
using namespace std;
typedef long long ll;
#define pb push_back
const int maxn=1e5+10;
const int N=0x3f3f3f3f;

struct node{
    int l,r;
};

vector  edge[maxn];
queue  que;
node pre[100];
ll sum[4*maxn],laz[4*maxn];
int f[maxn],fa[maxn],mp[maxn],lef1[maxn],rgt1[maxn],lef2[maxn],rgt2[maxn];
int n,q,uu,vv,num;

int getf(int p){
    if(f[p]==p) return p;
    else return f[p]=getf(f[p]);
}

bool unite(int u,int v){
    int fu,fv;
    fu=getf(u),fv=getf(v);
    if(fu!=fv){
        f[fv]=fu;
        return 1;
    }
    else return 0;
}

void bfs(){
    int i,u,v,cnt;
    while(!que.empty()) que.pop();
    que.push(1),fa[1]=0;
    cnt=0;
    while(!que.empty())
    {
        u=que.front();
        que.pop();
        mp[u]=++cnt;
        for(i=0;im) update(pl,pr,val,m+1,r,2*cur+1);
    pushup(cur);
}

ll query(int pl,int pr,int l,int r,int cur){
    ll res;
    int m;
    if(pl<=l&&r<=pr) return sum[cur];
    pushdown(l,r,cur);
    res=0,m=(l+r)/2;
    if(pl<=m) res+=query(pl,pr,l,m,2*cur);
    if(pr>m) res+=query(pl,pr,m+1,r,2*cur+1);
    return res;
}

bool cmp(node n1,node n2){
    return n1.lpre[j].r) pre[++j]=pre[i];
        else pre[j].r=max(pre[j].r,pre[i].r);
    }
    num=j;
}

int main(){
    ll d,res;
    int t,i,u,v,k;
    char op[10];
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(i=1;i<=n;i++) edge[i].clear();
        for(i=1;i<=n;i++) f[i]=i;
        for(i=1;i<=n;i++){
            scanf("%d%d",&u,&v);
            if(unite(u,v)) edge[u].pb(v),edge[v].pb(u);
            else uu=u,vv=v;
        }
        //printf("***%d %d***\n",uu,vv);
        bfs();
        init();
        scanf("%d",&q);
        while(q--){
            scanf("%s",op);
            if(op[0]=='M'){
                scanf("%d%d%lld",&u,&k,&d);
                if(k==0) update(mp[u],mp[u],d,1,n,1);
                else if(k==1){
                    num=0;
                    pre[++num].l=mp[fa[u]],pre[num].r=mp[fa[u]];
                    pre[++num].l=mp[u],pre[num].r=mp[u];
                    pre[++num].l=lef1[u],pre[num].r=rgt1[u];
                    if(u==uu) pre[++num].l=mp[vv],pre[num].r=mp[vv];
                    else if(u==vv) pre[++num].l=mp[uu],pre[num].r=mp[uu];
                    solve();
                    //for(i=1;i<=num;i++) printf("*%d %d*\n",pre[i].l,pre[i].r);
                    for(i=1;i<=num;i++) update(pre[i].l,pre[i].r,d,1,n,1);
                }
                else{
                    num=0;
                    pre[++num].l=mp[fa[fa[u]]],pre[num].r=mp[fa[fa[u]]];
                    pre[++num].l=mp[fa[u]],pre[num].r=mp[fa[u]];
                    pre[++num].l=lef1[fa[u]],pre[num].r=rgt1[fa[u]];
                    pre[++num].l=mp[u],pre[num].r=mp[u];
                    pre[++num].l=lef1[u],pre[num].r=rgt1[u];
                    pre[++num].l=lef2[u],pre[num].r=rgt2[u];
                    if(fa[u]==uu||fa[u]==vv||(lef1[u]<=mp[uu]&&mp[uu]<=rgt1[u])||(lef1[u]<=mp[vv]&&mp[vv]<=rgt1[u])){
                        if(fa[u]==vv||(lef1[u]<=mp[vv]&&mp[vv]<=rgt1[u])) swap(uu,vv);
                        pre[++num].l=mp[vv],pre[num].r=mp[vv];
                    }
                    else if(u==uu||u==vv){
                        if(u==vv) swap(uu,vv);
                        pre[++num].l=mp[fa[vv]],pre[num].r=mp[fa[vv]];
                        pre[++num].l=mp[vv],pre[num].r=mp[vv];
                        pre[++num].l=lef1[vv],pre[num].r=rgt1[vv];
                    }
                    solve();
                    //for(i=1;i<=num;i++) printf("*%d %d*\n",pre[i].l,pre[i].r);
                    for(i=1;i<=num;i++) update(pre[i].l,pre[i].r,d,1,n,1);
                }
            }
            else{
                scanf("%d%d",&u,&k);
                if(k==0) res=query(mp[u],mp[u],1,n,1);
                else if(k==1){
                    num=0;
                    pre[++num].l=mp[fa[u]],pre[num].r=mp[fa[u]];
                    pre[++num].l=mp[u],pre[num].r=mp[u];
                    pre[++num].l=lef1[u],pre[num].r=rgt1[u];
                    if(u==uu) pre[++num].l=mp[vv],pre[num].r=mp[vv];
                    else if(u==vv) pre[++num].l=mp[uu],pre[num].r=mp[uu];
                    solve();
                    res=0;
                    //for(i=1;i<=num;i++) printf("*%d %d*\n",pre[i].l,pre[i].r);
                    for(i=1;i<=num;i++) res+=query(pre[i].l,pre[i].r,1,n,1);
                }
                else{
                    num=0;
                    pre[++num].l=mp[fa[fa[u]]],pre[num].r=mp[fa[fa[u]]];
                    pre[++num].l=mp[fa[u]],pre[num].r=mp[fa[u]];
                    pre[++num].l=lef1[fa[u]],pre[num].r=rgt1[fa[u]];
                    pre[++num].l=mp[u],pre[num].r=mp[u];
                    pre[++num].l=lef1[u],pre[num].r=rgt1[u];
                    pre[++num].l=lef2[u],pre[num].r=rgt2[u];
                    if(fa[u]==uu||fa[u]==vv||(lef1[u]<=mp[uu]&&mp[uu]<=rgt1[u])||(lef1[u]<=mp[vv]&&mp[vv]<=rgt1[u])){
                        if(fa[u]==vv||(lef1[u]<=mp[vv]&&mp[vv]<=rgt1[u])) swap(uu,vv);
                        pre[++num].l=mp[vv],pre[num].r=mp[vv];
                    }
                    else if(u==uu||u==vv){
                        if(u==vv) swap(uu,vv);
                        pre[++num].l=mp[fa[vv]],pre[num].r=mp[fa[vv]];
                        pre[++num].l=mp[vv],pre[num].r=mp[vv];
                        pre[++num].l=lef1[vv],pre[num].r=rgt1[vv];
                    }
                    solve();
                    res=0;
                    //for(i=1;i<=num;i++) printf("*%d %d*\n",pre[i].l,pre[i].r);
                    for(i=1;i<=num;i++) res+=query(pre[i].l,pre[i].r,1,n,1);
                }
                printf("%lld\n",res);
            }
        }
    }
    return 0;
}

/*
1
18
1 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
7 10
7 11
7 12
8 13
8 14
10 15
10 16
12 17
12 18
6 15
10
M 6 1 5
M 6 2 5
M 6 0 5
M 15 1 2
Q 10 2
*/

 

你可能感兴趣的:(线段树/树状数组/RMQ)