【ZJOI2008】【BZOJ1036】树的统计Count
来源:互联网 发布:智能手机如何设置网络 编辑:程序博客网 时间:2024/04/26 04:50
开学就被送去开学考
寒假一点文化课都没搞你还考个毛(╯‵□′)╯︵┻━┻
最后果然还是挂了(不过至少还没出班里前十= =)
回机房第一天想了想决定再去写一个沙茶链剖
题目描述 Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。
我们将以下面的形式来要求你对这棵树完成一些操作:
I. CHANGE u t : 把结点u的权值改为t
II.QMAX u v: 询问从点u到点v的路径上的节点的最大权值
III.QSUM u v: 询问从点u到点v的路径上的节点的权值和
注意:从点u到点v的路径上的节点包括u和v本身
输入描述 Input Description
输入文件的第一行为一个整数n,表示节点的个数。
接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。 接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。 接下来1行,为一个整数q,表示操作的总数。
接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
输出描述 Output Description
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
样例输入 Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
样例输出 Sample Output
4
1
2
2
10
6
5
6
5
16
数据范围及提示 Data Size & Hint
对于100%的数据,保证1
想不到当年的浙江省选也会出裸题233
代码奇丑无比,不但长而且速度也比较慢(反正能AC就不管那么多了╮(╯▽╰)╭)
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXINT 0x7fffffff#define MAXN 100010#define lchild rt<<1,l,mid#define rchild rt<<1|1,mid+1,r#define ln rt<<1#define rn rt<<1|1using namespace std;int w[MAXN];int size[MAXN],deep[MAXN],chain[MAXN],num[MAXN],fa[MAXN][18];bool vis[MAXN];int top,tp;int a,b;int u,v;int n,q;char ch[6];struct edge{ edge *next; int to;}*prev[MAXN],e[MAXN*2];struct seg{ int maxn; int sum; int l; int r;}tree[MAXN*4];void insert(int u,int v){ e[++top].to=v; e[top].next=prev[u]; prev[u]=&e[top];}void dfs1(int x){ size[x]=1; vis[x]=1; for (int i=1;i<=17;i++) { if (deep[x]<(1<<i)) break; fa[x][i]=fa[fa[x][i-1]][i-1]; } for (edge *i=prev[x];i;i=i->next) { int t=i->to; if (vis[t]) continue; deep[t]=deep[x]+1; fa[t][0]=x; dfs1(t); size[x]+=size[t]; }}void dfs2(int x,int last){ chain[x]=last; num[x]=++tp; int t=0; for (edge *i=prev[x];i;i=i->next) if (deep[i->to]>deep[x]&&size[t]<size[i->to]) t=i->to; if (!t) return; dfs2(t,last); for (edge *i=prev[x];i;i=i->next) if (deep[i->to]>deep[x]&&i->to!=t) dfs2(i->to,i->to);}void build(int rt=1,int l=1,int r=n){ tree[rt].l=l; tree[rt].r=r; if (l==r) return; int mid=(l+r)>>1; build(lchild); build(rchild);}int lca(int a,int b){ if (deep[a]<deep[b]) swap(a,b); int t=deep[a]-deep[b]; for (int i=0;i<=17;i++) if (t&(1<<i)) a=fa[a][i]; for (int i=17;i>=0;i--) if (fa[a][i]!=fa[b][i]) { a=fa[a][i]; b=fa[b][i]; } if (a==b) return a; else return fa[a][0];}void modify(int rt,int x,int nu){ int L=tree[rt].l,R=tree[rt].r; int mid=(L+R)>>1; if (L==R) { tree[rt].maxn=tree[rt].sum=nu; return; } if (x<=mid) modify(ln,x,nu); else if (x>mid) modify(rn,x,nu); tree[rt].maxn=max(tree[ln].maxn,tree[rn].maxn); tree[rt].sum=tree[ln].sum+tree[rn].sum;}int query_sum(int rt,int l,int r){ int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1; if (L==l&&R==r) { return tree[rt].sum; } if (l>mid) return query_sum(rn,l,r); else if (r<=mid) return query_sum(ln,l,r); else return query_sum(lchild)+query_sum(rchild);}int query_max(int rt,int l,int r){ int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1; if (L==l&&R==r) { return tree[rt].maxn; } if (l>mid) return query_max(rn,l,r); else if (r<=mid) return query_max(ln,l,r); else return max(query_max(lchild),query_max(rchild));}int Query_sum(int a,int b){ int ret=0; while (chain[a]!=chain[b]) { ret+=query_sum(1,num[chain[a]],num[a]); a=fa[chain[a]][0]; } ret+=query_sum(1,num[b],num[a]); return ret;}int Query_max(int a,int b){ int ret=-MAXINT; while (chain[a]!=chain[b]) { ret=max(ret,query_max(1,num[chain[a]],num[a])); a=fa[chain[a]][0]; } ret=max(ret,query_max(1,num[b],num[a])); return ret;}int main(){ scanf("%d",&n); for (int i=1;i<n;i++) { scanf("%d%d",&u,&v); insert(u,v); insert(v,u); } for (int i=1;i<=n;i++) scanf("%d",&w[i]); scanf("%d",&q); dfs1(1); dfs2(1,1); build(); for (int i=1;i<=n;i++) modify(1,num[i],w[i]); while (q--) { scanf("%s",ch); if (ch[1]=='H') { scanf("%d%d",&a,&b); w[a]=b; modify(1,num[a],b); } else if (ch[1]=='M') { scanf("%d%d",&a,&b); int t=lca(a,b); printf("%d\n",max(Query_max(a,t),Query_max(b,t))); } else if (ch[1]=='S') { scanf("%d%d",&a,&b); int t=lca(a,b); printf("%d\n",Query_sum(a,t)+Query_sum(b,t)-w[t]); } }}
- [Bzoj1036][ZJOI2008]树的统计Count
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
- 【BZOJ1036】【ZJOI2008】树的统计Count 树链剖分裸题
- 【ZJOI2008】【BZOJ1036】树的统计Count
- [BZOJ1036][ZJOI2008]树的统计Count && LCT
- bzoj1036: [ZJOI2008]树的统计Count
- [BZOJ1036][ZJOI2008]树的统计Count
- 【bzoj1036】【树链剖分】【ZJOI2008】树的统计Count
- 【BZOJ1036】【ZJOI2008】【树的统计count】【树链剖分】
- bzoj1036: [ZJOI2008]树的统计Count
- BZOJ1036: [ZJOI2008]树的统计Count (树链剖分)
- bzoj1036: [ZJOI2008]树的统计Count - 树链剖分
- BZOJ1036: [ZJOI2008]树的统计Count
- bzoj1036【ZJOI2008】树的统计Count
- 【树链剖分】[BZOJ1036][ZJOI2008]树的统计Count
- [BZOJ1036] [ZJOI2008]树的统计Count
- [ZJOI2008] [BZOJ1036] 树的统计Count
- Android发短信代码
- 带省略号的 下一页
- 淘宝分布式 key/value 存储引擎Tair安装部署过程及Java客户端测试一例
- Java 操作符 小结
- 【SICP练习】106 练习3.7
- 【ZJOI2008】【BZOJ1036】树的统计Count
- 链家地产-Java工程师面试
- NodeJS事件的使用
- Lucene索引XML文件及单域,多域搜索
- NodeJS 初学小结
- 显示全部品牌
- 复制TXT文件 并且去掉TXT文件的空格回车
- hdu 1724 自适应simpson 或 romberg
- html之marquee详解