• [HDU5029]Relief grain(树链剖分+线段树)


    两种显然的做法:

    1.树上差分+线段树合并。$O(nlog n)$

    2.树链剖分转为序列上差分+线段树。$O(nlog^2 n)$

    后一种的代码:

     1 #include<cstdio>
     2 #include<vector>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #define ls (x<<1)
     7 #define rs (ls|1)
     8 #define lson ls,L,mid
     9 #define rson rs,mid+1,R
    10 #define mem(a) memset(a,0,sizeof(a))
    11 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
    12 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
    13 typedef long long ll;
    14 using namespace std;
    15 
    16 const int N=100010;
    17 int n,m,u,v,w,tim,cnt,id[N<<2],s[N<<2],to[N<<1],nxt[N<<1];
    18 int son[N],top[N],pos[N],d[N],sz[N],ans[N],fa[N],h[N];
    19 vector<int>V[N];
    20 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
    21 void init(){
    22     cnt=0; tim=0;
    23     rep(i,1,n) h[i]=son[i]=0,V[i].clear();
    24 }
    25 
    26 void dfs1(int x){
    27     sz[x]=1; d[x]=d[fa[x]]+1;
    28     For(i,x) if ((k=to[i])!=fa[x]){
    29         fa[k]=x; dfs1(k); sz[x]+=sz[k];
    30         if (sz[k]>sz[son[x]]) son[x]=k;
    31     }
    32 }
    33 
    34 void dfs2(int x,int z){
    35     pos[x]=++tim; top[x]=z;
    36     if (son[x]) dfs2(son[x],z);
    37     For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k);
    38 }
    39 
    40 void work(int l,int r,int c){ V[l].push_back(c),V[r+1].push_back(-c); }
    41 
    42 void solve(int u,int v,int c){
    43     for (; top[u]!=top[v]; u=fa[top[u]]){
    44         if (d[top[u]]<d[top[v]]) swap(u,v);
    45         work(pos[top[u]],pos[u],c);
    46     }
    47     if (d[u]>d[v]) swap(u,v);
    48     work(pos[u],pos[v],c);
    49 }
    50 
    51 void upd(int x){
    52     int k=s[ls]<s[rs] ? rs : ls;
    53     s[x]=s[k]; id[x]=id[k];
    54 }
    55 
    56 void build(int x,int L,int R){
    57     if (L==R){ s[x]=0; id[x]=L; return; }
    58     int mid=(L+R)>>1;
    59     build(lson); build(rson); upd(x);
    60 }
    61 
    62 void ins(int x,int L,int R,int pos,int k){
    63     if (L==R){ s[x]+=k; return; }
    64     int mid=(L+R)>>1;
    65     if (pos<=mid) ins(lson,pos,k); else ins(rson,pos,k);
    66     upd(x);
    67 }
    68 
    69 int main(){
    70     freopen("hdu5029.in","r",stdin);
    71     freopen("hdu5029.out","w",stdout);
    72     while (scanf("%d%d",&n,&m)==2 && n+m){
    73         init(); int mx=0;
    74         rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
    75         fa[1]=0; dfs1(1); dfs2(1,1);
    76         rep(i,1,m) scanf("%d%d%d",&u,&v,&w),solve(u,v,w),mx=max(mx,w);
    77         build(1,0,mx);
    78         rep(i,1,n){
    79             rep(j,0,(int)V[i].size()-1)
    80                 if (V[i][j]>0) ins(1,0,mx,V[i][j],1); else ins(1,0,mx,-V[i][j],-1);
    81             ans[i]=id[1];
    82         }
    83         rep(i,1,n) printf("%d
    ",ans[pos[i]]);
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Android studio快捷键大全 和 eclipse对照(原)
    .net 提取注释生成API文档 帮助文档
    查看443端口被占用无法启动解决办法
    关于正则表达式 C#
    关于 ImageLoader 说的够细了。。。
    什么时候用Application的Context,什么时候用Activity的Context
    关于layoutparam 请铭记。。。。
    java 静态方法上的泛型
    让多个Fragment 切换时不重新实例化
    开源.net 混淆器ConfuserEx介绍
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9880356.html
Copyright © 2020-2023  润新知