bzoj 1036
来源:互联网 发布:sqlserver基础知识 编辑:程序博客网 时间:2024/05/22 12:55
一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 I
II. QSUM u v: 询问从点u到点v的路径上的节点的权值和
分析:树链剖分
技能:
for (;belong[x]^belong[y];)
{
if (deep[belong[x]]<deep[belong[y]]) swap(x,y);
ans+=query(1,1,n,pos[belong[x]],pos[x]);
x=fa[belong[x]];
}
deep[belong[x]]<deep[belong[y]比较的是链顶的深度大小
代码:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;++i)
#define dep(i,j,k) for (int i=j;i>=k;--i)
#define to e[i].v
#define Cl(a) memset(a,0,sizeof(a))
#define N 30010
#define inf 1235467890
struct node{
int v,next;
}e[N<<2];
int Max[N<<2],sum[N<<2],fa[N<<2],pos[N<<2],size[N<<2],head[N<<2],deep[N<<2],belong[N<<2];
int id,n,m,sz;
int read()
{
int f=1,x=0;char ch=getchar();
for (;ch>'9'||ch<'0';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*f;
}
void add(int u,int v)
{
e[id].v=v;
e[id].next=head[u];
head[u]=id++;
}
void dfs1(int u)
{
size[u]=1;
for (int i=head[u];i;i=e[i].next)
if (to^fa[u])
{
deep[to]=deep[u]+1;
fa[to]=u;
dfs1(to);
size[u]+=size[to];
}
}
void dfs2(int u,int chain)
{
pos[u]=++sz; belong[u]=chain; int k=0;
for (int i=head[u];i;i=e[i].next)
if (deep[to]>deep[u] && size[to]>size[k]) k=to;
if (k==0) return; dfs2(k,chain);
for (int i=head[u];i;i=e[i].next)
if (deep[to]>deep[u] && k^to) dfs2(to,to);
}
void pushup(int root)
{
Max[root]=max(Max[root<<1],Max[root<<1|1]);
sum[root]=sum[root<<1]+sum[root<<1|1];
}
int query_Max(int root,int l,int r,int L,int R)
{
if (L<=l && r<=R) return Max[root];
int mid=l+r>>1,Mx=-inf;
if (L<=mid) Mx=max(query_Max(root<<1,l,mid,L,R),Mx);
if (mid<R) Mx=max(query_Max(root<<1|1,mid+1,r,L,R),Mx);
return Mx;
}
int query(int root,int l,int r,int L,int R)
{
if (L<=l && r<=R) return sum[root];
int mid=l+r>>1,ans=0;
if (L<=mid) ans+=query(root<<1,l,mid,L,R);
if (mid<R) ans+=query(root<<1|1,mid+1,r,L,R);
return ans;
}
void insert(int root,int l,int r,int x,int y)
{
if (l==r)
{
sum[root]=Max[root]=y;
return;
}
int mid=l+r>>1;
if (x<=mid) insert(root<<1,l,mid,x,y);
if (mid<x) insert(root<<1|1,mid+1,r,x,y);
pushup(root);
}
void swap(int &a,int &b) {int t=a;a=b;b=t;}
int Query(int x,int y)
{
int ans=0;
for (;belong[x]^belong[y];)
{
if (deep[belong[x]]<deep[belong[y]]) swap(x,y);
ans+=query(1,1,n,pos[belong[x]],pos[x]);
x=fa[belong[x]];
}
if (pos[x]>pos[y]) swap(x,y);
ans+=query(1,1,n,pos[x],pos[y]);
return ans;
}
int Query_Max(int x,int y)
{
int Mx=-inf;
for (;belong[x]^belong[y];)
{
if (deep[belong[x]]<deep[belong[y]]) swap(x,y);
Mx=max(query_Max(1,1,n,pos[belong[x]],pos[x]),Mx);
x=fa[belong[x]];
}
if (pos[x]>pos[y]) swap(x,y);
Mx=max(query_Max(1,1,n,pos[x],pos[y]),Mx);
return Mx;
}
int main()
{
n=read(); id=1;
rep(i,1,n-1)
{
int u=read(),v=read();
add(u,v); add(v,u);
}
dfs1(1);
dfs2(1,1);
rep(i,1,n)
{
int x=read();
insert(1,1,n,pos[i],x);
}
m=read(); char ch[10];
rep(i,1,m)
{
scanf("%s",ch+1);
if (ch[1]=='C')
{
int x=read(),y=read();
insert(1,1,n,pos[x],y);
}
else if (ch[1]=='Q' && ch[2]=='S')
{
int x=read(),y=read();
printf("%d\n",Query(x,y));
}
else
{
int x=read(),y=read();
printf("%d\n",Query_Max(x,y));
}
}
return 0;
}
- bzoj 1036
- bzoj 1036
- bzoj 1036
- bzoj 1036
- bzoj 1036 树链剖分
- BZOJ 1036 树链剖分
- bzoj 1036 [LCT version]
- BZOJ 1036 树链剖分
- bzoj 1036 树链剖分模板
- bzoj 1036(树链剖分)
- [BZOJ ]
- BZOJ****-****
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BZOJ
- BeCoolCmsx下表单里日期选择器的使用
- 第二章 关于MapReduce
- iOS内置购买之提交指南-协议、税务和银行业务
- qt 学习
- JavaScript 模块化开发一瞥
- bzoj 1036
- 洛谷 P1282 多米诺骨牌 (背包dp)
- java 线程实时监控硬盘文件目录的文件操作状态
- java反射机制在代理模式中的使用
- C语言中换行符和回车符的区别
- build.gradle其他配置信息
- BRVAH官方使用指南(持续更新)
- java自学-java开发环境搭建
- lua 安装