hdu 3966 树链分割第一3遍

真的不好意思说话。你写得越多,对风暴各种问题泄露,更离谱,有什么错有。。

。但是,仍然有一个。同时经过规范的编写清晰的代码。不能认为是理所当然。。。

树桩阵列版:

#include<cstdio>
#include<cstring>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
using namespace std;
const int M = 50100;
int son[M],top[M],father[M],dep[M],ti[M],siz[M];
int idx,tp,n;
struct {
    int head;
}H[M];
struct {
    int v,next;
}E[M];
void dfs_1(int u,int fa){
    son[u] = 0;siz[u] = 1;father[u] = fa;dep[u] = dep[fa] + 1;
    for(int i=H[u].head;i!=-1;i=E[i].next){
        int v = E[i].v;
        if(v == fa)continue;
        dfs_1(v,u);
        siz[u] += siz[v];
        if(siz[son[u]] < siz[v])son[u] = v;
    }
}
void dfs_2(int u,int fa){
    top[u] = fa;
    ti[u] = idx++;
    if(son[u]) dfs_2(son[u],fa);
    for(int i=H[u].head;i!=-1;i=E[i].next){
        int v = E[i].v;
        if(v == father[u]|| v == son[u])continue;
        dfs_2(v,v);
    }
}
int lobit(int x){
    return x&(-x);
}
int num[M*2];
void update(int x ,int d){
    while( x <= n){
        num[x] += d;
        x += lobit(x);
    }
}
void change(int u,int v,int w){
    int f1 = top[u];
    int f2 = top[v];
    while(f1 != f2){
        if(dep[f1] <dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        update(ti[f1],w);
        update(ti[u]+1,-w);
        u = father[f1];f1 = top[u];
    }
    if(dep[u] > dep[v])swap(u,v);
    update(ti[u],w);
    update(ti[v]+1,-w);
}
int sum(int x){
    int ans = 0;
    while(x>0){
        ans += num[x];
        x -= lobit(x);
    }
    return ans;
}

void add(int u,int v){
    E[tp].v = v;
    E[tp].next = H[u].head;
    H[u].head = tp++;
}
void init(){
    memset(E,-1,sizeof(E));
    memset(H,-1,sizeof(H));
    memset(num,0,sizeof(num));
    tp = 0;
    idx = 1;
}
int findp(int x){
    return sum(ti[x]);
}
int a[M];
int main(){
   // freopen("input.txt","r",stdin);
    int m,p,u,v,w;
    while(scanf("%d%d%d",&n,&m,&p)==3){
    init();
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        while(m -- ){
            scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        dfs_1(1,1);
        dfs_2(1,1);
        for(int i=1;i<=n;i++){
           update(ti[i],a[i]);
           update(ti[i]+1,-a[i]);
        }

        char op[100];
        while (p--){
            scanf("%s%d",op,&u);
            if(op[0] == 'Q'){
                printf("%d\n",sum(ti[u]));
            }else {
                scanf("%d%d",&v,&w);
                if(op[0] == 'D')w = -w;
                change(u,v,w);
            }
        }

    }
}<span style="background-color: rgb(255, 0, 0);">
</span>

线段树版:

#pragma comment(linker,"/STACK:100000000,100000000")
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define lson id << 1
#define rson id << 1 | 1
const int M = 50010;
int a[M],top[M],ti[M],son[M],father[M],siz[M],dep[M];
int tp,idx;
struct {
    int head;
}H[M*2];
struct {
    int v,next;
}E[M*4];
void add(int u,int v){
    E[tp].v = v;
    E[tp].next = H[u].head;
    H[u].head = tp++;
}
void dfs_1(int u,int fa){
    son[u] = 0;siz[u] =1;dep[u] = dep[fa] + 1;father[u] = fa;
    for(int i=H[u].head;i!=-1;i=E[i].next){
        int v = E[i].v;
        if(v == fa)continue;
        dfs_1(v,u);
        siz[u] += siz[v];
        if(siz[v] > siz[son[u]])son[u] = v;

    }
}
void dfs_2(int u,int fa){
    ti[u] = ++idx;top[u] = fa;
    if(son[u])dfs_2(son[u],fa);
    for(int i=H[u].head;i!=-1;i=E[i].next){
        int v  =  E[i].v;
        if(v == father[u]||v == son[u])continue;
        dfs_2(v,v);
    }
}
/* 线段树*/

struct Lintree{
    int l,r,w,mark;
    int mid(){
        return (l+r) / 2;
    }
}node[M*4];
void build_tree(int id,int l,int r){
    node[id].l = l;
    node[id].r = r;
    node[id].mark = 0;
    if(l == r)return;

    int mid = node[id].mid();
    build_tree(lson,l,mid);
    build_tree(rson,mid+1,r);
}
void push_down(int id){
    if(node[id].mark){
        node[lson].mark += node[id].mark;
        node[rson].mark += node[id].mark;
        node[id].mark = 0;
    }
}
void update(int id,int l,int r,int w){
    if(node[id].l == l && node[id].r == r){
           // cout <<"dfasf -->" <<l<<"dfsf" <<r<<endl;
        node[id].mark+=w;
        return;
    }
    push_down(id);
    int mid = node[id].mid();
    if(r <=mid)update(lson,l,r,w);
    else if(l > mid)update(rson,l,r,w);
    else {
        update(lson,l,mid,w);
        update(rson,mid+1,r,w);
    }
}
int query(int id,int x){
    if(node[id].l == x&&node[id].r == x ){
           // cout <<"<sdf>"<< node[id].w<<endl;
        return node[id].mark;
    }
    push_down(id);
    int mid = node[id].mid();
    if(x <=mid)return query(lson,x);
    else return  query(rson,x);
}
void change(int u,int v,int x){
   // cout <<u<<"**"<<v<<endl;
   int f1 = top[u],f2 = top[v];
   while(f1 != f2){
        if(dep[f1] < dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        update(1,ti[f1],ti[u],x);
        u = father[f1];f1 = top[u];
   }
   //if(u == v)return
   if(dep[u] > dep[v])swap(u,v);
   update(1,ti[u],ti[v],x);
}
void init(){
    memset(E,-1,sizeof(E));
    memset(H,-1,sizeof(H));
    tp = idx = 0;
}
int main(){
    int n,m,p,u,v,w;
    //freopen("input.txt","r",stdin);
    while(~scanf("%d%d%d",&n,&m,&p)){
       init();

       for(int i=1;i<=n;i++)
          scanf("%d",&a[i]);
       while(m--) {
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
         }
        dfs_1(1,1);
        dfs_2(1,1);
        build_tree(1,1,n);
       char op[1000];

        while(p--){
            scanf("%s",op);
            if(op[0] == 'Q'){
                scanf("%d",&u);
            printf("%d\n",query(1,ti[u])+a[u]);
            }else {
                scanf("%d%d%d",&u,&v,&w);
                if(op[0] == 'D') w = -w;
                change(u,v,w);

            }
        }
    }
}

版权声明:本文博主原创文章。博客,未经同意不得转载。

时间: 2024-10-12 23:18:51

hdu 3966 树链分割第一3遍的相关文章

hdu 3966 树链剖分第3遍

真心不好意思说话,写的越多,各种问题就暴漏出来了,这次更离谱,什么错误都有...不过还是过了.也明白了代码以后要写规范性,不能想当然... #include<cstdio> #include<cstring> #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<algorithm> using namespace std;

HDU 3966 (树链剖分+线段树)

Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板题. 实质上树链剖分进行了点对点的一次映射,保证了重链上的点在线段树上的位置是连续的. 树链剖分的两个性质(转): 性质1:如果(v,u)为轻边,则siz[u] * 2 < siz[v]: 性质2:从根到某一点的路径上轻链.重链的个数都不大于logn. 保证了一个区间的时间复杂度是log2(n).

Hdu 3804 树链剖分 第5遍

不能原谅自己的错误..还怀疑人家的数据错了,瞬间感觉自己弱爆了 #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstring> #include<algorithm> #define lson id << 1 #define rson id << 1|1 #include<cstdio> usi

HDU 2966 Aragorn&#39;s Story 树链剖分第一题 基础题

Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of his kingdom and M edges c

HDU 5274(树链剖分)

树链剖分第一题QAQ,纪念下 #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const ll mod = 1e9 + 7; const int maxn = 1e5 + 10; #define

hdu 5893 (树链剖分+合并)

List wants to travel Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 429    Accepted Submission(s): 92 Problem Description A boy named List who is perfect in English. Now he wants to travel an

hdu 5052 树链剖分

Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 982    Accepted Submission(s): 274 Problem Description Yaoge likes to eat chicken chops late at night. Yaoge has eaten too

hdu 5242 树链剖分找权值最大的前k条链

http://acm.hdu.edu.cn/showproblem.php?pid=5242 Problem Description It is well known that Keima Katsuragi is The Capturing God because of his exceptional skills and experience in ''capturing'' virtual girls in gal games. He is able to play k games sim

hdu 5274 树链剖分

Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1484    Accepted Submission(s): 347 Problem Description Dylans is given a tree with N nodes. All nodes have a value A[i].Nodes