列表

详情


NC15505. 抓fafa的qzh

描述

冬天又过去了,春天又来了,Alice和Bob又开始玩游戏了(雾

    

Alice和Bob开始玩一个小游戏,但他们觉得并不好玩,于是把这个游戏给了最可爱的fafa和最坏坏的qzh,fafa和qzh觉得很有趣,就玩了起来

这是在一棵树上的游戏,树的形态将会给出,所有树的边长度都为1

最可爱的fafa拥有一种高端的技巧,可以将自己化身为多个可爱度不同的fafa,每次轮到fafa行动时,fafa都会在点u到点v路径上所有的点都放一只可爱度为w的fafa,每个点可以同时存在多个fafa

最坏坏的qzh不喜欢可爱的生物,于是他要去抓可爱度l到可爱度r的fafa。起初qzh站在点p上,他想要知道他离所有可爱度为l到r的fafa的距离和到底是多少来决定他要不要离开他的笔记本

注意:因为fafa本体非常强大,所以坏坏的qzh并不能真的去抓fafa,也就是说,树上的fafa会不断增多,但坏坏的qzh只能看着这棵树越来越可爱,以及想(y)象(y)着去抓可爱的fafa

坏坏的qzh觉得很不开心,而且他的笔记本和脑子跑的都很慢,并不能解决这个问题,所以他把这个问题交给了你,你需要回答他每次询问的距离和是多少


输入描述

第一行输入两个数n,m,分别表示数的点数和询问的次数
第2行到第n行共计n-1行每行输入两个数a,b,表示点a和点b之间有一条边(数据保证是一棵树)
接下来m行,每行第一个数为1或者2,表示两种操作
1:读入u,v,w,表示在点u到点v的路径上都放一只可爱度为w的fafa
2:读入l,r,p,表示一只站在点p上的qzh想知道他距离所有可爱度为l到r之间([l,r])的距离和是多少

输出描述

输出若干行,每行包括一个整数,对于每个操作2需要输出,但操作1不需要

示例1

输入:

10 20
6 7
1 2
5 4
1 3
10 8
7 9
1 8
1 4
2 6
1 5 1 27280262
1 2 4 27245688
2 27234840 27290934 6
1 10 6 27227228
2 27313334 27321446 3
1 9 10 27258713
1 3 4 27249714
2 27270810 27309316 1
1 9 2 27254034
2 27292791 27302394 10
1 7 5 27319311
1 5 6 27301947
1 10 1 27318014
2 27247634 27320484 9
1 10 5 27299018
2 27240281 27286743 8
2 27296751 27319246 4
2 27309633 27314750 9
2 27257490 27301409 6
2 27235007 27294034 2

输出:

15
0
3
0
112
46
20
0
38
32

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 5473ms, 内存消耗: 48232K, 提交时间: 2018-04-07 15:48:33

#include<bits/stdc++.h>
using namespace std;

#define FOR(a,b,c) for(int a=(b),a##_end__=(c);a<a##_end__;++a)
#define DOR(a,b,c) for(int a=(b)-1,a##_end__=(c);a>=a##_end__;--a)
#define ll long long
template<class T>inline bool chkmin(T&a,T const&b){return a>b?a=b,true:false;}
template<class T>inline bool chkmax(T&a,T const&b){return a<b?a=b,true:false;}
const int M=100005;
const int S=1200;
const int N=M/S+5;
const int K=18;
struct Node{int u,v,x;}Q[M];
vector<int> E[M];
int Log2[M<<1],ST[M<<1][K],Eulorn[M],Dep[M];
int dfsv[M],Fa[M],P[M];
ll Val[N][M],dp[M],APS[M];
int n,m,w,q,Eulor_cnt,dfn_cnt;
 
void dfs(int u,int fa){
    ST[++Eulor_cnt][0]=u;
    dfsv[++dfn_cnt]=u;
    Eulorn[u]=Eulor_cnt;
    for(auto v:E[u]) if(v^fa){
        Fa[v]=u;
        Dep[v]=Dep[u]+1;
        dfs(v,u);
        ST[++Eulor_cnt][0]=u;
    }
}
inline int dep_min(int u,int v){return Dep[u]<Dep[v]?u:v;}
void ST_table(){
    FOR(k,1,K) FOR(i,1,(n<<1)-(1<<k)+1)
        ST[i][k]=dep_min(ST[i][k-1],ST[i+(1<<k-1)][k-1]);
}
inline int LCA(int u,int v){
    u=Eulorn[u],v=Eulorn[v];
    if(u>v) swap(u,v);
    int k=Log2[v-u+1];
    return dep_min(ST[u][k],ST[v-(1<<k)+1][k]);
}
inline ll Query(int u,int v,int x){
    int o=LCA(u,v),p=LCA(u,x),q=LCA(v,x),r=LCA(o,x);
    if(Dep[p]<Dep[q]) swap(p,q),swap(u,v);
    int Do=Dep[o],Du=Dep[u],Dv=Dep[v],Dp=Dep[p];
    int sum=Du+Dv-(Do<<1)+1;
    if(o!=r) return (ll)(Do+Dep[x]-(Dep[r]<<1))*sum+APS[Dv-Do]+APS[Du-Do];
    return (ll)(Dep[x]-Dp)*sum+APS[Du-Dp]+APS[Dp+Dv-(Do<<1)];
}
 
void build(Node *Q,ll *Val){
    FOR(i,0,M) P[i]=dp[i]=Val[i]=0;
    FOR(i,0,S){
        int u=Q[i].u,v=Q[i].v,x=LCA(u,v);
        P[u]++,P[v]++,P[x]--,P[Fa[x]]--;
    }
    DOR(i,n+1,1){
        int u=dfsv[i],v=Fa[u];
        P[v]+=P[u];
        dp[v]+=dp[u]+=P[u];
        Val[v]+=Val[u]+dp[u];
    }
    FOR(i,1,n+1){
        int u=dfsv[i];
        Val[u]=Val[Fa[u]]+dp[1]-(dp[u]<<1);
    }
}

int main(){
    FOR(i,2,M<<1) Log2[i]=Log2[i>>1]+1;
    FOR(i,0,M) APS[i]=(ll)i*(i+1)>>1;
    scanf("%d %d",&n,&q);
    FOR(i,1,n){
        int u,v;
        scanf("%d %d",&u,&v);
        E[u].push_back(v);
        E[v].push_back(u);
    }
    dfs(1,-1);
    ST_table();
    while(q--){
        int op,x,y,z;
        scanf("%d %d %d %d",&op,&x,&y,&z);
        if(op&1){
            Q[w++]={x,y,z};
            if(w%S==0){
            	auto cmp=[](Node A,Node B){return A.x<B.x;};
                sort(Q+m,Q+w,cmp);
                inplace_merge(Q,Q+m,Q+w,cmp);
                FOR(i,0,(m=w)/S) build(Q+i*S,Val[i]);
            }
        }
        else{
            ll res=0;
            FOR(i,m,w) if(x<=Q[i].x && Q[i].x<=y) res+=Query(Q[i].u,Q[i].v,z);
            int L=lower_bound(Q,Q+m,x,[](Node A,int x){return A.x<x;})-Q;
            int R=upper_bound(Q,Q+m,y,[](int x,Node A){return x<A.x;})-Q;
            if(L/S==R/S) FOR(i,L,R) res+=Query(Q[i].u,Q[i].v,z);
            else{
                FOR(i,L/S+1,R/S) res+=Val[i][z];
                FOR(i,L,L/S*S+S) res+=Query(Q[i].u,Q[i].v,z);
                FOR(i,R/S*S,R) res+=Query(Q[i].u,Q[i].v,z);
            }
            printf("%lld\n",res);
        }
    }
    return 0;
}

上一题