【poj3237】【link-cut tree】Tree
2013-05-13 07:55
232 查看
题目大意:
给你一颗树,要求支持下列3个操作:
1.询问两点之间路径的边中边权最大的;
2.把两点之间的路径的边权全部取反;
3.修改某条边的边权。
很明显的动态树模型,首先要把边权转化为点权,并且要在dfs的时候记录每条边的权值在哪个点里面。
操作1和3是常规操作。
对于操作2,我们对每个节点记录Max和Min,取反就等价于Max = -Min,Min = -Max
代码:
给你一颗树,要求支持下列3个操作:
1.询问两点之间路径的边中边权最大的;
2.把两点之间的路径的边权全部取反;
3.修改某条边的边权。
很明显的动态树模型,首先要把边权转化为点权,并且要在dfs的时候记录每条边的权值在哪个点里面。
操作1和3是常规操作。
对于操作2,我们对每个节点记录Max和Min,取反就等价于Max = -Min,Min = -Max
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 10000 + 10; const int inf = 0x3f3f3f3f; struct Edge { int pos,cost; int next; }E[maxn<<2]; int head[maxn]; int Max[maxn],Min[maxn],w[maxn]; int ch[maxn][2],pre[maxn],belong[maxn<<2]; bool neg[maxn]; int T,NE,n; void init() { freopen("poj3237.in","r",stdin); freopen("poj3237.out","w",stdout); } inline int min(int a,int b) { return a < b ? a : b; } inline int max(int a,int b) { return a > b ? a : b; } void swap(int &a,int &b) { int t = a;a = b;b = t; } void add(int u,int v,int w) { ++NE; E[NE].pos = v;E[NE].cost = w; E[NE].next = head[u];head[u] = NE; } void Init() { memset(E,0,sizeof(E)); memset(head,-1,sizeof(head)); memset(Min,0x3f,sizeof(Min)); memset(Max,~0x3f,sizeof(Max)); memset(w,0,sizeof(w)); memset(neg,false,sizeof(neg)); memset(ch,0,sizeof(ch)); memset(pre,0,sizeof(pre)); NE = 0;w[1] = -inf; } void dfs(int u,int f) { for(int i = head[u];i != -1;i = E[i].next) { int v = E[i].pos; if(v == f)continue; belong[(i + 1) >> 1] = v; w[v] = E[i].cost; pre[v] = u; dfs(v,u); } } void update(int x) { Min[x] = min(w[x],min(Min[ ch[x][0] ],Min[ ch[x][1] ])); Max[x] = max(w[x],max(Max[ ch[x][0] ],Max[ ch[x][1] ])); } void makeneg(int x) { if(x != 0) { neg[x] = !neg[x]; w[x] = -w[x]; int t = Max[x]; Max[x] = -Min[x];Min[x] = -t; } } void push_down(int x) { if(neg[x]) { makeneg(ch[x][0]); makeneg(ch[x][1]); neg[x] = false; } } bool isroot(int x) { return ch[pre[x]][0] != x && ch[pre[x]][1] != x; } void down_all(int x) { if(!isroot(x))down_all(pre[x]); push_down(x); } void Rotate(int x,int f) { int y = pre[x]; ch[y][!f] = ch[x][f]; pre[ ch[x][f] ] = y; pre[x] = pre[y]; if(ch[ pre[y] ][0] == y)ch[ pre[y] ][0] = x; else if(ch[ pre[y] ][1] == y)ch[ pre[y] ][1] = x; pre[y] = x; ch[x][f] = y; update(y); } void splay(int x) { down_all(x); while(!isroot(x)) { if(isroot(pre[x]))Rotate(x,ch[ pre[x] ][0] == x); else { int y = pre[x],z = pre[y]; int f = (ch[z][0] == y); if(ch[y][f] == x)Rotate(x,!f),Rotate(x,f); else Rotate(y,f),Rotate(x,f); } } update(x); } void access(int u) { for(int v = 0;u;v = u,u = pre[u]) { splay(u); ch[u][1] = v; update(u); } } void modify(int p,int key) { splay(p); w[p] = key; update(p); } int query(int a,int b) { int x = a,y = b; access(y); for(y = 0;x;y = x,x = pre[x]) { splay(x); if(!pre[x])return max(Max[ ch[x][1] ],Max[y]); ch[x][1] = y; update(x); } return 0; } void negate(int a,int b) { int x = a,y = b; access(y); for(y = 0;x;y = x,x = pre[x]) { splay(x); if(!pre[x]) { makeneg(ch[x][1]); makeneg(y); return; } ch[x][1] = y; update(x); } } void readdata() { scanf("%d",&T); while(T--) { Init(); scanf("%d",&n); for(int i = 1;i < n;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } dfs(1,-1); char op[10]; while(true) { scanf("%s",op); int a,b; if(!strcmp(op,"DONE"))break; scanf("%d%d",&a,&b); if(!strcmp(op,"CHANGE"))a = belong[a],modify(a,b); if(!strcmp(op,"QUERY"))printf("%d\n",query(a,b)); if(!strcmp(op,"NEGATE"))negate(a,b); } } } int main() { init(); readdata(); return 0; }
相关文章推荐
- 【Luogu1501】Tree(Link-Cut Tree)
- 【BZOJ3282】Tree【Link-Cut Tree】
- BZOJ 3282 Tree ——Link-Cut Tree
- 【SPOJ-QTREE】Query on a tree【Link-Cut Tree】
- 【BZOJ3282】Tree (Link-Cut Tree)
- BZOJ 2631 Tree ——Link-Cut Tree
- 动态树(Link Cut Tree) :SPOJ 375 Query on a tree
- bzoj 2631 Tree [Link-Cut Tree]
- SPOJ QTREE3 Query on a tree again! ——Link-Cut Tree
- 【Luogu1501】Tree(Link-Cut Tree)
- bzoj 2631(link cut tree)
- SplayTree指针模板 & LinkCutTree指针模板
- 学习一个LinkCutTree
- Link-Cut Tree(Insider Preview)
- bzoj 2594: 水管局长数据加强版 Link-Cut-Tree
- 【SDOI2008】【link-cut tree】洞穴勘测
- 【hdu4010】【link-cut tree】Query on The Trees
- 【POJ3237】Tree(树链剖分)
- 【Codeforces Round 339 (Div 2)A】【水题 暴力】 LinkCut Tree 输出[l,r]范围内所有的k的幂数
- [POJ3237]Tree 做题笔记