【ZJOI2008】【link-cut tree】树的统计
来源:互联网 发布:天池竞赛用什么算法 编辑:程序博客网 时间:2024/06/04 01:13
这道题写了比较久。。。主要是手残比较多
关键的一点是由于题目直接给出了树的每条边,所以建树要用dfs来建,我最开始使用access(x)然后pre[x] = y的方法要WA,不过我感觉这样做是对的。。。当然这种感觉上对的方法不但是错的,而且效率肯定不如dfs
其他的就是动态树的基本操作了,没什么好说的。
代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 30000 + 10;const int maxm = 100000;const int inf = 0x3f3f3f3f;struct pnode{int pos;pnode *next;pnode(){}pnode(int pos,pnode *next):pos(pos),next(next){}}*first[maxn], __[maxm],*tot = __;int ch[maxn][2],pre[maxn];int sum[maxn],Max[maxn],w[maxn];bool rev[maxn];int n,m;void init(){freopen("count.in","r",stdin);freopen("count.out","w",stdout);}void update(int x){sum[x] = sum[ ch[x][0] ] + sum[ ch[x][1] ] + w[x];Max[x] = max(w[x],max(Max[ ch[x][0] ],Max[ ch[x][1] ]));if(rev[x]){swap(ch[x][0],ch[x][1]);rev[ ch[x][0] ] = !rev[ ch[x][0] ];rev[ ch[x][1] ] = !rev[ ch[x][1] ];rev[x] = false;}}bool isroot(int x){return ch[pre[x]][0] != x && ch[pre[x]][1] != x;}void push_down(int x){if(!isroot(x))push_down(pre[x]);update(x);}void rotate(int x,int f){int y = pre[x],z = pre[y];ch[y][!f] = ch[x][f];pre[ ch[x][f] ] = y;pre[x] = pre[y];if(ch[z][0] == y)ch[z][0] = x;else if(ch[z][1] == y)ch[z][1] = x;pre[y] = x;ch[x][f] = y;update(y);}void splay(int x){push_down(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 evert(int x){access(x);splay(x);rev[x] = !rev[x];}void link(int a,int b){evert(a);pre[a] = b;update(a);}int query(int x,int y,bool flag){access(y);for(y = 0;x;y = x,x = pre[x]){splay(x);if(!pre[x]){if(!flag)return max(w[x],max(Max[ch[x][1]],Max[y]));else return sum[ch[x][1]] + sum[y] + w[x];}ch[x][1] = y;update(x);}return 0;}void modify(int t,int key){w[t] = key;splay(t);}void dfs(int u,int f){for(pnode *p = first[u];p != NULL;p = p -> next){int v = p -> pos;if(v == f)continue;dfs(v,u);pre[v] = u;}}void readdata(){memset(Max,~0x3f,sizeof(Max));memset(ch,0,sizeof(ch));memset(rev,false,sizeof(rev));scanf("%d",&n);for(int i = 1;i < n;i++){int u,v;scanf("%d%d",&u,&v);first[u] = new(tot++)pnode(v,first[u]);first[v] = new(tot++)pnode(u,first[v]);}for(int i = 1;i <= n;i++)scanf("%d",&w[i]);w[0] = Max[0] = -inf;dfs(1,0);scanf("%d",&m);for(int i = 1;i <= m;i++){char op[10];int a,b;scanf("%s%d%d",op,&a,&b);if(!strcmp(op,"QMAX"))printf("%d\n",query(a,b,0));if(!strcmp(op,"QSUM"))printf("%d\n",query(a,b,1));if(!strcmp(op,"CHANGE"))modify(a,b);}}int main(){init();readdata();return 0;}
- 【ZJOI2008】【link-cut tree】树的统计
- bzoj1036: [ZJOI2008]树的统计Count [Link-Cut-Tree/树链剖分]
- bzoj1036 [ZJOI2008]树的统计Count (树链剖分|Link Cut Tree)
- BZOJ 题目1036: [ZJOI2008]树的统计Count(Link Cut Tree,修改点权求两个最大值和最大值)
- 动态树 Link Cut Tree
- 【ZJOI2008】树的统计
- 【ZJOI2008】树的统计
- 【ZJOI2008】树的统计
- 【ZJOI2008】树的统计
- 树的统计 ZJOI2008
- [ZJOI2008]树的统计
- Link-Cut-Tree 的基本姿势
- 【动态树初探】link-cut tree
- 【动态树初探】link-cut tree
- BZOJ 3306 树 Link-Cut-Tree+set
- 学习笔记-动态树Link-Cut-Tree
- Link-Cut-Tree 动态树算法
- xsy1025 link-cut-tree+线段树
- listView1.SelectedItems选中行要注意count>0
- android
- 在Windows上开发PHP扩展模块
- 【转载】〖ASP.NET〗ASP.NET的五大数据控件浅谈
- C++ vector的定义及使用
- 【ZJOI2008】【link-cut tree】树的统计
- 串口从1~17全部被占用解决办法
- 对于校赛F题的一些思考
- struct tm 和 time_t 时间和日期的使用方法(转)
- allegro pcb editor stroke研究
- The Mythical Man-Month: The Tar Pit
- pthread 快排 基础版
- Comparable在排序中的作用
- 机器学习中的算法-svm学习