D - Tree

Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=6547

The meaning of problems: Given a tree, there are two modes of operation, the right path and query point, each point on the path square root rounded down.

Ideas: tree chain operations, 1e9 open up to 10 times the square root is 1, we only need to open a variable period of maintenance intervals are not all 1 on it.

#include " stdio.h " 
#include " string.h " 
#include " math.h " 
#include " algorithm " 
the using  namespace STD; 
typedef Long  Long LL;
 const  int N = 200010 ; 

int n-, Q, the root, MOD;
 int head [N], Ver [N], the Next [N], TOT; /// tree structure storage 
LL Val [N]; /// storing information of each node 
int D [N], Son [N ], FAR [N], Size [N]; /// junction depth, heavy son, ancestors 
LL SUM [N * . 4 ];/// junction of line segment tree, maxx, sum value 
int DFN [N], top [N], id [N]; /// storage dfs order, top strand of ancestors, id each junction indexing position in the sequence of points in dfn 
int CNT; /// represents the last position dfs sequence 
int Laze [N * . 4 ], now [N * . 4 ];
 int NUM [N * . 4 ]; 

void the Add ( int X, int Y) { /// add side of the tree 
    Ver [TOT ++] = Y; the Next [TOT] = head [X]; head [X] = TOT; 
} 

void Build_Tree ( int ID, int L, int R & lt) 
{ 
    Laze [ID] = now [ID] =0; num[id] = 0;
    if(l == r)
    {
        laze[id] = 0; now[id] = 0;
        sum[id] = val[dfn[l]]; return ;
    }
    int mid = (l + r) >> 1;
    Build_Tree(id * 2,l,mid);
    Build_Tree(id * 2 + 1,mid + 1,r);
    sum[id] = sum[id * 2] + sum[id * 2 + 1];
    return ;
}


void Update(int id,int L,int R,int l,int r)///将loc上的值进行更新
{
    if(l <= L && r >= R && num[id] >= 6)
    {
        return ;
    }
    if(L == R)
    {
        sum[id] = (ll)sqrt(sum[id]);
        num[id] ++;
        return ;
    }
    int mid = (L + R) >> 1;
    if(l <= mid) Update(id * 2,L,mid,l,r);
    if(r > mid) Update(id * 2 + 1,mid + 1,R,l,r);
    sum[id] = sum[id * 2] + sum[id * 2 + 1];
    now[id] = min(now[id * 2],now[id * 2 + 1]);
    return ;
}

ll Query_sum(int id,int L,int R,int l,int r)///查询[l,r]区间和
{
    if(L > r || R < l) return 0;
     IF (L <= R & lt && L> = R & lt) 
        { 
            return SUM [ID]; 
        } 
    int MID = (L + R & lt) >> . 1 ; 
    LL ANS = Query_sum (ID * 2 , L, MID, L, R & lt) Query_sum + (ID * 2 + . 1 , MID + . 1 , R & lt, L, R & lt);
     return ANS; 
} 

void DFS1 ( int U, int F, int DEP) /// DFS1 d array processing means, son array, far array, Size array 
{ 
    D [U] = DEP; FAR [U] = F; 
    Size [U] = . 1 ; Son [U] = - . 1;
    for(int i = head[u]; i; i = Next[i]){
        int v = ver[i];
        if(v == f) continue;
        dfs1(v,u,dep+1);
        Size[u] += Size[v];
        if(son[u] == -1 || Size[son[u]] < Size[v])
           son[u] = v;
    }
}

void dfs2(int u,int T)///旨在处理重链,和dfs序列
{
    dfn[++ cnt] = u;id[u] = cnt;
    top[u] = T;
    if(son[u] == -1) return ;
    dfs2(son[u],T);
    for(int i = head[u]; i; i = Next[i]){
        int v = ver[i];
        if(v != son[u] && v != far[u]){
            dfs2(v,v);
        }
    }
}

int main()
{
    scanf("%d%d",&n,&q);
    for(int i = 1; i <= n; i ++)
    {
        scanf("%lld",&val[i]);
    }
    for(int i = 1; i < n; i ++)
    {
        int x,y; scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    cnt = 0;root = 1;
    dfs1(root,root,1);
    dfs2(root,root);
    Build_Tree(1,1,n);

    while(q --)
    {
       int op; scanf("%d",&op); op ++;
       if(op == 1)
       {
           int u,v; scanf("%d%d",&u,&v);
           int fu = top[u],fv = top[v];
           int ans = 0;
            while(fu != fv)
            {
                if(d[fu] >= d[fv])
                {
                    Update(1,1,n,id[fu],id[u]);
                    u = far[fu]; fu = top[u];
                } else {
                    Update(1,1,n,id[fv],id[v]);
                    v = far[fv]; fv = top[v];
                }
            }
            if(id[u] < id[v]) Update(1,1,cnt,id[u],id[v]);
            else Update(1,1,cnt,id[v],id[u]);
       }
       if(op == 2)
       {
           int u,v; scanf("%d%d",&u,&v);
           int fu = top[u],fv = top[v];
            ll ans = 0;
            while(fu != fv)
            {
                if(d[fu] >= d[fv])
                {
                    ans += Query_sum(1,1,n,id[fu],id[u]);
                    u = far[fu]; fu = top[u];
                } else {
                    ans += Query_sum(1,1,n,id[fv],id[v]);
                    v = far[fv]; fv = top[v];
                }
            }
            if(id[u] < id[v]) ans += Query_sum(1,1,cnt,id[u],id[v]);
            else ans += Query_sum(1,1,cnt,id[v],id[u]);
            printf("%lld\n",ans);
       }
    }
}

 

Guess you like

Origin www.cnblogs.com/zcb123456789/p/12368904.html