zoukankan      html  css  js  c++  java
  • BZOJ 1036 树的统计(树链剖分)

    点权树链剖分模板题。

    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    # include <iostream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <set>
    # include <cmath>
    # include <algorithm>
    using namespace std;
    # define lowbit(x) ((x)&(-x))
    # define pi acos(-1.0)
    # define eps 1e-9
    # define MOD 1000000007
    # define INF 1000000000
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define FO(i,a,n) for(int i=a; i<n; ++i)
    # define bug puts("H");
    # define lch p<<1,l,mid
    # define rch p<<1|1,mid+1,r
    # define mp make_pair
    # define pb push_back
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    # pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;
    int Scan() {
        int res=0, flag=0;
        char ch;
        if((ch=getchar())=='-') flag=1;
        else if(ch>='0'&&ch<='9') res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')  res=res*10+(ch-'0');
        return flag?-res:res;
    }
    void Out(int a) {
        if(a<0) {putchar('-'); a=-a;}
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=30005;
    //Code begin...
    
    struct Edge{int p, next;}edge[N<<1];
    int head[N], cnt, node[N], n;
    int seg[N<<2][2], fa[N], size[N], dep[N], p[N], top[N], son[N], pos;
    
    void add_edge(int u, int v){edge[cnt].p=v; edge[cnt].next=head[u]; head[u]=cnt++;}
    void init(){cnt=1; mem(son,-1); pos=1;}
    void dfs(int x, int pre, int d)
    {
        fa[x]=pre; dep[x]=d; size[x]=1;
        for (int i=head[x]; i; i=edge[i].next) {
            int v=edge[i].p;
            if (v==pre) continue;
            dfs(v,x,d+1);
            size[x]+=size[v];
            if (son[x]==-1||size[v]>size[son[x]]) son[x]=v;
        }
    }
    void get_pos(int x, int sp)
    {
        top[x]=sp; p[x]=pos++;
        if (son[x]==-1) return ;
        get_pos(son[x],sp);
        for (int i=head[x]; i; i=edge[i].next) {
            int v=edge[i].p;
            if (v!=son[x]&&v!=fa[x]) get_pos(v,v);
        }
    }
    void push_up(int p)
    {
        seg[p][0]=max(seg[p<<1][0], seg[p<<1|1][0]);
        seg[p][1]=seg[p<<1][1]+seg[p<<1|1][1];
    }
    void update(int p, int l, int r, int L, int val)
    {
        if (L>r||L<l) return ;
        if (L==l&&L==r) seg[p][0]=seg[p][1]=val;
        else {
            int mid=(l+r)>>1;
            update(lch,L,val); update(rch,L,val);
            push_up(p);
        }
    }
    int query(int p, int l, int r, int L, int R, int flag)
    {
        if (L>r||R<l) {
            if (flag) return 0;
            else return -INF;
        }
        if (L<=l&&R>=r) return seg[p][flag];
        int mid=(l+r)>>1;
        if (flag) return query(lch,L,R,flag)+query(rch,L,R,flag);
        else return max(query(lch,L,R,flag),query(rch,L,R,flag));
    }
    int Qtree(int l, int r, int flag)
    {
        int f1=top[l], f2=top[r], ans;
        if (flag) ans=0;
        else ans=-INF;
        bool mark=false;
        while (f1!=f2) {
            mark=true;
            if (dep[f1]<dep[f2]) swap(f1,f2), swap(l,r);
            if (flag==0) ans=max(ans,query(1,1,n,p[f1],p[l],flag));
            else ans+=query(1,1,n,p[f1],p[l],flag);
            l=fa[f1]; f1=top[l];
        }
        if (dep[l]>dep[r]) swap(l,r);
        if (flag==0) ans=max(ans,query(1,1,n,p[l],p[r],flag));
        else ans+=query(1,1,n,p[l],p[r],flag);
        return ans;
    }
    int main ()
    {
        int u, v, q, l, r;
        char flag[10];
        init();
        scanf("%d",&n);
        FO(i,1,n) scanf("%d%d",&u,&v), add_edge(u,v), add_edge(v,u);
        dfs(1,0,0);
        get_pos(1,1);
        FOR(i,1,n) scanf("%d",node+i), update(1,1,n,p[i],node[i]);
        scanf("%d",&q);
        while (q--) {
            scanf("%s%d%d",flag,&l,&r);
            if (flag[0]=='C') update(1,1,n,p[l],r);
            else printf("%d
    ",Qtree(l,r,flag[1]=='S'));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    2021“MINIEYE杯”中国大学生算法设计超级联赛(2)(1002 I love tree)(树状数组+树链剖分)
    周末随笔_有关变化
    20210808心情随笔
    离开那个傻叉的地方了
    如何建设符合ISO9000要求的企业文控中心
    企业云盘部署极其简单的分布式文件系统的方法
    企业云盘安全机制-文件加密存储与原文存储的优劣
    查看tomcat打开的文件数
    Centos7 Memcached 安装
    centos7 快速安装rabbitmq
  • 原文地址:https://www.cnblogs.com/lishiyao/p/6496249.html
Copyright © 2011-2022 走看看