HDU - 5044(树链剖分)
来源:互联网 发布:股票 数据 阿里云 编辑:程序博客网 时间:2024/05/02 06:45
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>using namespace std;#pragma comment(linker,"/STACK:102400000,102400000")const int maxn = 111111;long long ADD1[maxn],ADD2[maxn];int side,node,wei[maxn],link[maxn],lnode[maxn];//先转化为有根树int fa[maxn]; //每个结点的父节点int w[maxn]; //每个结点的与其父节点的连边在线段树中的位置int top[maxn]; //每条重链中其首节点;int dep[maxn]; //每个节点的深度;int son[maxn]; //每个节点的重儿子int siz[maxn];//vector<int> eson[maxn];int tot,head[maxn*2]; struct Edge{ int to,next; }edge[maxn*2];void addedge(int u,int v){ edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;}void init_dfs(int u){siz[u]=1; son[u]=0;for(int i = head[u];i != -1; i = edge[i].next)if(edge[i].to!=fa[u]){ int v=edge[i].to; fa[v]=u; dep[v]=dep[u]+1; init_dfs(v); if(siz[son[u]]< siz[v]) son[u]=v; siz[u]+=siz[v];}}void build_tree(int u,int tp){w[u]=side++; top[u]=tp; wei[u]=node++;if(son[u]!=0) { build_tree(son[u],tp);}for(int i = head[u];i != -1; i = edge[i].next)if(edge[i].to!=fa[u]&&edge[i].to!=son[u]){ build_tree(edge[i].to,edge[i].to);}}void init(int n){for(int i=0;i<=n;i++) ADD1[i]=ADD2[i]=0;fa[1]=1; dep[1]=0; top[1]=1;init_dfs(1);side=0; node=1;build_tree(1,1);}int ql,qr,addv;int find(int u,int v){int f1=top[u],f2=top[v];int res=0;while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(u,v); } ql=w[f1]; qr=w[u]+1; ADD2[ql]+=addv; ADD2[qr]-=addv; u=fa[f1]; f1=top[u];}if(u==v) return res;if(dep[u]<dep[v]) swap(u,v);ql=w[son[v]]; qr=w[u]+1;ADD2[ql]+=addv;ADD2[qr]-=addv;}void find_node(int u,int v){int f1=top[u],f2=top[v];int res=0;while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(u,v); } ql=wei[f1]; qr=wei[u]+1; ADD1[ql]+=addv; ADD1[qr]-=addv; u=fa[f1]; f1=top[u];}if(dep[u]<dep[v]) swap(u,v);ql=wei[v]; qr=wei[u]+1;ADD1[ql]+=addv;ADD1[qr]-=addv;}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');}int d[maxn][3];int main(){ int T; int n,kase=1; scanf("%d",&T); while(T--){ int Q; scan_d(n); scan_d(Q); int x,y,z; tot=0; memset(head,-1,sizeof(head)); for(int i=1;i<n;i++){ scan_d(x); scan_d(y); d[i][0]=x; d[i][1]=y; d[i][2]=0; addedge(d[i][0],d[i][1]); addedge(d[i][1],d[i][0]); } init(n); for(int i=1;i<n;i++){ if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]); } char cmd[100]; while(Q--){ int u,v; scanf("%s",cmd); scan_d(u); scan_d(v); scan_d(addv); if(cmd[3]=='1'){ find_node(u,v); } else find(u,v); } for(int i=1;i<=n;i++){ ADD1[i]+=ADD1[i-1]; ADD2[i]+=ADD2[i-1]; } printf("Case #%d:\n",kase++); for(int i=1;i<=n;i++){ if(i!=1) printf(" "); out(ADD1[wei[i]]); } printf("\n"); for(int i=1;i<n;i++){ if(i!=1) printf(" "); out(ADD2[w[d[i][1]]]); } printf("\n"); } return 0;}
本题时间卡的很严;很多地方需注意,输入输出加挂,o(1)的改,o(1)的查,主题方法为树链剖分,实现邻接表的存储用链表形式
0 0
- HDU - 5044(树链剖分)
- HDU 5044 - Tree (树链剖分)
- HDU 5044 Tree(树链剖分)
- HDU 5044 Tree (树链剖分)
- hdu 5044 Tree(树链剖分)
- HDU 5044 Tree (树链剖分)
- HDU 5044 Tree 树链剖分
- HDU 5044 Tree 树链剖分
- 【HDU】5044 Tree 树链剖分
- hdu 5044树链剖分
- hdu 5044 Tree 树链剖分
- hdu 5044 树链剖分
- hdu 5044 树链剖分
- hdu 5044 Tree(树链剖分)
- HDU 5044 Tree --树链剖分
- hdu 5044 Tree 树链剖分
- HDU 5044Tree 树链剖分
- HDU-5044 Tree 树链剖分
- ios手势识别(双击、捏、旋转、拖动、划动、长按, 上下左右滑动)
- android客户端与php服务器的json数据简单交互(一)
- 以编码的方式实现Auto Layout自动布局(一)
- 冒泡排序-插入排序-快速排序-选择排序---飞天博客
- 享元模式(Flyweight)
- HDU - 5044(树链剖分)
- 我的文档
- 单点登陆的简单实现
- XMPP学习及使用2
- Junit简单复习
- UML中类图的四种关系及其代码实现
- 电子商务与供应链管理
- 口碑化营销、零成本推广
- Adding a frame (C++)