树链剖分

来源:互联网 发布:申请淘宝店铺注册时间 编辑:程序博客网 时间:2024/05/13 22:58

树链剖分  模板  kuangbin 博客 copy

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int MAXN = 100010;struct Edge{int to,next;}edge[MAXN*2];int head[MAXN],tot;int top[MAXN];int fa[MAXN];int deep[MAXN];int num[MAXN];int p[MAXN];int fp[MAXN];int son[MAXN];int pos;void init(){tot = 0;memset(head,-1,sizeof(head));pos = 1;memset(son,-1,sizeof(son));}inline void addedge(int u,int v){edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;}inline void dfs1(int u,int pre,int d){deep[u] = d;fa[u] = pre;num[u] = 1;for(int i = head[u];i != -1;i = edge[i].next){int v = edge[i].to;if(v != pre){dfs1(v,u,d+1);num[u] += num[v];if(son[u] == -1 || num[v] > num[son[u]])son[u] = v;}}}inline void getpos(int u,int sp){top[u] = sp;p[u] = pos++;fp[p[u]] = u;if(son[u] == -1)return;getpos(son[u],sp);for(int i = head[u];i != -1;i = edge[i].next){int v = edge[i].to;if(v != son[u] && v != fa[u])getpos(v,v);}}long long w1[MAXN];void add1(int u,int v,int w){int f1 = top[u],f2 = top[v];while(f1 != f2){if(deep[f1] < deep[f2]){swap(f1,f2);swap(u,v);}w1[p[f1]] += w;w1[p[u]+1] -= w;u = fa[f1];f1 = top[u];}if(deep[u] > deep[v])swap(u,v);w1[p[u]] += w;w1[p[v]+1] -= w;}long long w2[MAXN];void add2(int u,int v,int w){int f1 = top[u], f2 = top[v];while(f1 != f2){if(deep[f1] < deep[f2]){swap(f1,f2);swap(u,v);}w2[p[f1]] += w;w2[p[u]+1] -= w;u = fa[f1];f1 = top[u];}if(u == v)return;if(deep[u] > deep[v])swap(u,v);w2[p[son[u]]] += w;w2[p[v]+1] -= w;}//适用于正负整数template <class T>inline bool scan_d(T &ret) {   char c; int sgn;   if(c=getchar(),c==EOF) return 0; //EOF   while(c!='-'&&(c<'0'||c>'9')) c=getchar();   sgn=(c=='-')?-1:1;   ret=(c=='-')?0:(c-'0');   while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');   ret*=sgn;   return 1;}inline void out(long long x) {   if(x>9) out(x/10);   putchar(x%10+'0');}pair<int,int>pp[MAXN];int link[MAXN];long long ans1[MAXN],ans2[MAXN];int main(){    int n,m;int T;int iCase = 0;scanf("%d",&T);while(T--){iCase++;init();scan_d(n);scan_d(m);memset(w1,0,sizeof(w1));memset(w2,0,sizeof(w2));int u,v,w;for(int i = 1;i < n;i++){scan_d(u);scan_d(v);addedge(u,v);addedge(v,u);pp[i] = make_pair(u,v);}dfs1(1,0,0);getpos(1,1);for(int i = 1;i < n;i++){if(deep[pp[i].first] > deep[pp[i].second])swap(pp[i].first,pp[i].second);link[pp[i].second] = i;}char op[10];while(m--){scanf("%s",op);scan_d(u);scan_d(v);scan_d(w);if(op[3] == '1'){add1(u,v,w);}else add2(u,v,w);}for(int i = 1;i <= n;i++){w1[i] += w1[i-1];w2[i] += w2[i-1];ans1[fp[i]] = w1[i];ans2[link[fp[i]]] = w2[i];}printf("Case #%d:\n",iCase);for(int i = 1;i <= n;i++){//printf("%I64d",ans1[i]);out(ans1[i]);if(i < n)printf(" ");else printf("\n");}for(int i = 1;i < n;i++){//printf("%I64d",ans2[i]);out(ans2[i]);if(i < n-1)printf(" ");}printf("\n");}    return 0;}


0 0
原创粉丝点击