Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 11102 Solved: 4490
[Submit][Status][Discuss]
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
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
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
1
2
2
10
6
5
6
5
16
HINT
Source
- #include<bits/stdc++.h>
- using namespace std;
- #define lson k*2,l,mid
- #define rson k*2+1,mid+1,r
- #define MAXN 30010
- #define INF 1e9
- struct node
- {
- int begin,end,next;
- }edge[MAXN*];
- struct NODE
- {
- int left,right,sum,mx,val;
- }tree[*MAXN];
- int cnt,Head[MAXN],val[MAXN],deep[MAXN],size[MAXN],P[MAXN][],belong[MAXN],pos[MAXN],SIZE,n;
- bool vis[MAXN];
- void addedge(int bb,int ee)
- {
- edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
- }
- void addedge1(int bb,int ee)
- {
- addedge(bb,ee);addedge(ee,bb);
- }
- int read()
- {
- int s=,fh=;char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
- while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
- return s*fh;
- }
- void dfs1(int u)
- {
- int i,v;
- size[u]=;vis[u]=true;
- for(i=Head[u];i!=-;i=edge[i].next)
- {
- v=edge[i].end;
- if(vis[v]==false)
- {
- deep[v]=deep[u]+;
- P[v][]=u;
- dfs1(v);
- size[u]+=size[v];
- }
- }
- }
- void Ycl()
- {
- int i,j;
- for(j=;(<<j)<=n;j++)
- {
- for(i=;i<=n;i++)
- {
- if(P[i][j-]!=-)P[i][j]=P[P[i][j-]][j-];
- }
- }
- }
- void dfs2(int u,int chain)
- {
- int k=,i,v;
- pos[u]=++SIZE;belong[u]=chain;
- for(i=Head[u];i!=-;i=edge[i].next)
- {
- v=edge[i].end;
- if(deep[v]>deep[u]&&size[v]>size[k])k=v;
- }
- if(k==)return;
- dfs2(k,chain);
- for(i=Head[u];i!=-;i=edge[i].next)
- {
- v=edge[i].end;
- if(deep[v]>deep[u]&&v!=k)dfs2(v,v);
- }
- }
- int LCA(int x,int y)
- {
- int i,j;
- if(deep[x]<deep[y])swap(x,y);
- for(i=;(<<i)<=deep[x];i++);i--;
- for(j=i;j>=;j--)if(deep[x]-(<<j)>=deep[y])x=P[x][j];
- if(x==y)return x;
- for(j=i;j>=;j--)
- {
- if(P[x][j]!=-&&P[x][j]!=P[y][j])
- {
- x=P[x][j];
- y=P[y][j];
- }
- }
- return P[x][];
- }
- void Pushup(int k)
- {
- tree[k].sum=tree[k*].sum+tree[k*+].sum;
- tree[k].mx=max(tree[k*].mx,tree[k*+].mx);
- }
- void Build(int k,int l,int r)
- {
- tree[k].left=l;tree[k].right=r;
- if(l==r)return;
- int mid=(l+r)/;
- Build(lson);
- Build(rson);
- }
- void Change(int k,int P,int V)
- {
- if(tree[k].left==tree[k].right)
- {
- tree[k].val=tree[k].sum=tree[k].mx=V;
- return;
- }
- int mid=(tree[k].left+tree[k].right)/;
- if(P<=mid)Change(k*,P,V);
- else Change(k*+,P,V);
- Pushup(k);
- }
- int Query_max(int k,int l,int r)
- {
- if(l<=tree[k].left&&tree[k].right<=r)return tree[k].mx;
- int mid=(tree[k].left+tree[k].right)/;
- if(r<=mid)return Query_max(k*,l,r);
- else if(l>mid)return Query_max(k*+,l,r);
- else return max(Query_max(k*,l,mid),Query_max(k*+,mid+,r));
- }
- int Query_sum(int k,int l,int r)
- {
- if(l<=tree[k].left&&tree[k].right<=r)return tree[k].sum;
- int mid=(tree[k].left+tree[k].right)/;
- if(r<=mid)return Query_sum(k*,l,r);
- else if(l>mid)return Query_sum(k*+,l,r);
- else return Query_sum(k*,l,mid)+Query_sum(k*+,mid+,r);
- }
- int solve_max(int x,int f)
- {
- int MAX=-INF;
- while(belong[x]!=belong[f])
- {
- MAX=max(MAX,Query_max(,pos[belong[x]],pos[x]));
- x=P[belong[x]][];
- }
- MAX=max(MAX,Query_max(,pos[f],pos[x]));
- return MAX;
- }
- int solve_sum(int x,int f)
- {
- int SUM=;
- while(belong[x]!=belong[f])
- {
- SUM+=Query_sum(,pos[belong[x]],pos[x]);
- x=P[belong[x]][];
- }
- SUM+=Query_sum(,pos[f],pos[x]);
- return SUM;
- }
- int main()
- {
- freopen("bzoj_1036.in","r",stdin);
- freopen("bzoj_1036.out","w",stdout);
- int m,i,bb,ee,u,v,t,lca;
- char zs[];
- n=read();
- memset(Head,-,sizeof(Head));cnt=;
- for(i=;i<n;i++)
- {
- bb=read();ee=read();addedge1(bb,ee);
- }
- memset(P,-,sizeof(P));SIZE=;
- dfs1();Ycl();
- dfs2(,);
- for(i=;i<=n;i++)val[i]=read();
- Build(,,n);
- for(i=;i<=n;i++)Change(,pos[i],val[i]);
- m=read();
- for(i=;i<=m;i++)
- {
- scanf("\n%s",zs);
- if(zs[]=='C'){u=read();t=read();val[u]=t;Change(,pos[u],val[u]);}
- else
- {
- if(zs[]=='M')
- {
- u=read();v=read();
- lca=LCA(u,v);
- printf("%d\n",max(solve_max(u,lca),solve_max(v,lca)));
- }
- else {u=read();v=read();lca=LCA(u,v);printf("%d\n",solve_sum(u,lca)+solve_sum(v,lca)-val[lca]);}
- }
- }
- fclose(stdin);
- fclose(stdout);
- return ;
- }
Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14968 Solved: 6079[Submit][Stat ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)
[ZJOI2008]树的统计Count ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比 时间限制:5 s 内存限制:162 MB [题目描述] 一棵树上有n ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- 配置php连接apache
配置php连接apache 1.安装php所需要的库 yum install zlib-devel libxml2-devel libjpeg-devel libjpeg-turbo-devel li ...
- scp 命令使用
scp 是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且 scp传输是加密的.可能会稍微影响一下速度.当你服 ...
- nfs,ftp配置
一. NFS1. NFS简介NFS全称是network file systemNFS允许一个系统在网络上与他人共享目录和文件.通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件. 假 ...
- zlib1.2.8 编译小记
官网下载:http://www.zlib.net/ 用vs命令行工具运行zlib-1.2.8\contrib\masmx86\bld_ml32.bat 用vs2012打开zlib-1.2.8\cont ...
- HTML5:一个拖拽网页元素的例子
关键字:HTML5, Drag&Drop, JavaScript, CSS 运行环境:Chrome <!DOCTYPE html> <html> <head> ...
- sqlsever2008数据库的备份与还原
本文数据库的名称为ProjectControl public static SqlConnection conn = new SqlConnection("server=(local);u ...
- NS实现采用的技术大多是PHP,如果采用java、 .net是否同样适用?
SNS采用的技术可不都是PHP (不局限于国内),特别是国外的新兴公司,基本上没有再用PHP的了,国内到还是蛮常用的.简单说说我知道的几个案例:Facebook (PHP):Facebook采用PHP ...
- 关于Java(Hello World程序)
详解 Hello World 应用程序 源码 class HelloWorldApp { public static void main(String[] args) { System.out.pri ...
- bzoj 1187: [HNOI2007]神奇游乐园 插头dp
1187: [HNOI2007]神奇游乐园 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 668 Solved: 337[Submit][Statu ...
- 修改sphinx最大输出记录数
修改sphinx最大输出记录数 归纳如下: Sphinx的查询默认最大记录数是:1000,而我们想更改这个数值.就需要更改三个地方. 1是更改sphinx.conf配置文件的:max_matches ...