BZOJ P2157 旅游
题目大意:
维护一棵树,每条边有边权,支持下列操作:
1.修改某条边的边权
2.将某条路经上的边权取反
3.询问某条路经上的和
4.询问某条路经上的最大值
5.询问某条路经上的最小值
--by BZOJ;
http://www.lydsy.com/JudgeOnline/problem.php?id=2157
有关树链剖分的详解,见:树链剖分
链剖模板,代码长了点,主要是线段树部分操作太多,注意可以把边权搞到点上;
代码如下:
#include<cstdio>
#define INF 0x3fffffff
using namespace std;
struct ss{
int to,next,dis;
}x[];
int first[],num;
int size[];//子树和//
int hway[];//重边//
int rank[];//点在line_tree中的位置//
int rankl[];//边所对点在line_tree中的位置//
int dis[];//点权 //
int top[];//重链顶 //
int dep[];//深度 //
int fa[];//父亲//
int a[];//line_tree的原line序列//
int ltre[];
int max[];
int min[];
int lz[];
int n,m,L,R,X,W;
void swap(int&,int&);
void build(int ,int ,int );
void dfs_1(int );
void dfs_2(int ,int );
void up(int );
void down(int ,int ,int );
void builtre(int ,int ,int );
void work(int );
int wor_(int ,int );
void chan1(int ,int ,int );
void chan2(int ,int ,int );
int sum(int ,int ,int );
int Max(int ,int ,int );
int Min(int ,int ,int );
int main()
{
int i,j,k,l;
char s[];
scanf("%d",&n);
for(i=;i<=n-;i++)
hway[i]=i;
for(i=;i<=n-;i++){
scanf("%d%d%d",&j,&k,&l);
build(j,k,l);
build(k,j,l);
}
dep[]=;
dfs_1();
num=;
dfs_2(,);
num=;
builtre(,n,);
scanf("%d",&m);
for(i=;i<=m;i++){
scanf("%s",s);
scanf("%d%d",&L,&R);
if(s[]!='\0')s[]=s[];
if(s[]=='C')X=rankl[L],W=R;
switch (s[]){
case 'C': chan1(,n,);break;//C
case 'N': work();break;//N
case 'U': work();break;//NUM
case 'A': work();break;//MAX
case 'I': work();break;//MIN
}
}
}
void swap(int &a,int &b){
int i;
i=a;a=b;b=i;
}
void build(int f,int t,int l){
x[++num].next=first[f];
x[num].dis=l;
x[num].to=t;
first[f]=num;
}
void dfs_1(int now){
int j=first[now];
while(j){
if(!dep[x[j].to]){
dis[x[j].to]=x[j].dis;
dep[x[j].to]=dep[now]+;
fa[x[j].to]=now;
dfs_1(x[j].to);
size[now]+=size[x[j].to];
if(hway[now]==now||size[x[j].to]>size[hway[now]])
hway[now]=x[j].to;
}
j=x[j].next;
}
size[now]++;
}
void dfs_2(int now,int to_nu){
int j=first[now];
top[now]=to_nu;
rank[now]=++num;
a[num]=now;
if(hway[now]!=now)
dfs_2(hway[now],to_nu);
while(j){
if(dep[x[j].to]>dep[now]&&x[j].to!=hway[now])
rankl[(j+)>>]=num+,dfs_2(x[j].to,x[j].to);
if(x[j].to==hway[now])
rankl[(j+)>>]=rank[hway[now]];
j=x[j].next;
}
}
void up(int nu){
ltre[nu]=ltre[nu<<]+ltre[nu<<|];
max[nu]=max[nu<<]>max[nu<<|]?max[nu<<]:max[nu<<|];
min[nu]=min[nu<<]<min[nu<<|]?min[nu<<]:min[nu<<|];
}
void down(int l,int r,int nu){
if(!lz[nu]) return;
lz[nu<<]^=;lz[nu<<|]^=;
swap(max[nu<<],min[nu<<]);
max[nu<<]=-max[nu<<]; min[nu<<]=-min[nu<<];
ltre[nu<<]=-ltre[nu<<];
swap(max[nu<<|],min[nu<<|]);
max[nu<<|]=-max[nu<<|]; min[nu<<|]=-min[nu<<|];
ltre[nu<<|]=-ltre[nu<<|];
lz[nu]=;
}
void builtre(int l,int r,int nu){
if(l==r){
max[nu]=min[nu]=ltre[nu]=dis[a[++num]];
if(a[num]==){
max[nu]=-INF;
min[nu]=INF;
}
return;
}
int mid=(l+r)>>;
builtre(l,mid,nu<<);
builtre(mid+,r,nu<<|);
up(nu);
}
void work(int x){
int ans=;
if(x==)ans=-INF;
if(x==)ans=INF;
int u=L,v=R;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])
L=rank[top[v]],R=rank[v],v=fa[top[v]];
else
L=rank[top[u]],R=rank[u],u=fa[top[u]];
ans=wor_(ans,x);
}
if(u!=v){
if(dep[u]>dep[v])
swap(u,v);
u=hway[u];
L=rank[u];R=rank[v];
ans=wor_(ans,x);
}
if(x>=)
printf("%d\n",ans);
}
int wor_(int ans,int x){
int i;
if(x==)
chan2(,n,);
if(x==)
ans+=sum(,n,);
if(x==){
i=Max(,n,);ans=ans>i?ans:i;}
if(x==){
i=Min(,n,);ans=ans<i?ans:i;}
return ans;
}
void chan1(int l,int r,int nu){
if(l==r){
max[nu]=min[nu]=ltre[nu]=W ;
return;
}
int mid=(l+r)>>;
down(l,r,nu);
if(X<=mid)
chan1(l,mid,nu<<);
if(X>mid)
chan1(mid+,r,nu<<|);
up(nu);
}
void chan2(int l,int r,int nu){
if(L<=l&&r<=R){
swap(max[nu],min[nu]);
max[nu]=-max[nu];
min[nu]=-min[nu];
ltre[nu]=-ltre[nu];
lz[nu]^=;
return ;
}
down(l,r,nu);
int mid=(l+r)>>;
if(L<=mid)
chan2(l,mid,nu<<);
if(R>mid)
chan2(mid+,r,nu<<|);
up(nu);
}
int sum(int l,int r,int nu){
if(L<=l&&r<=R)
return ltre[nu];
down(l,r,nu);
int mid=(l+r)>>,re=;
if(L<=mid)
re+=sum(l,mid,nu<<);
if(R>mid)
re+=sum(mid+,r,nu<<|);
return re;
}
int Max(int l,int r,int nu){
if(L<=l&&r<=R)
return max[nu];
down(l,r,nu);
int mid=(l+r)>>,lm=-INF,rm=-INF;
if(L<=mid)
lm=Max(l,mid,nu<<);
if(R>mid)
rm=Max(mid+,r,nu<<|);
if(lm>=rm)
return lm;
return rm;
}
int Min(int l,int r,int nu){
if(L<=l&&r<=R)
return min[nu];
down(l,r,nu);
int mid=(l+r)>>,lm=INF,rm=INF;
if(L<=mid)
lm=Min(l,mid,nu<<);
if(R>mid)
rm=Min(mid+,r,nu<<|);
if(lm<=rm)
return lm;
return rm;
}
祝AC哟;
BZOJ P2157 旅游的更多相关文章
- BZOJ 2157: 旅游( 树链剖分 )
树链剖分.. 样例太大了根本没法调...顺便把数据生成器放上来 -------------------------------------------------------------------- ...
- bzoj 2157: 旅游 (LCT 边权)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2157 题面; 2157: 旅游 Time Limit: 10 Sec Memory Lim ...
- 【刷题】BZOJ 2157 旅游
Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间 ...
- BZOJ 2157: 旅游
2157: 旅游 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1347 Solved: 619[Submit][Status][Discuss] ...
- bzoj [POI2007]旅游景点atr 状态压缩+Dij
[POI2007]旅游景点atr Time Limit: 30 Sec Memory Limit: 357 MBSubmit: 2258 Solved: 595[Submit][Status][D ...
- bzoj 2657 旅游
Written with StackEdit. Description 到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~ 经过一番抉择,两人决定将\(T\)国作为他们 ...
- BZOJ 2157: 旅游 (2017.7.21 6:30-2017.7.21 15:38 今日第一题。。)
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1754 Solved: 765 Description Ray 乐忠于旅游,这次他来到了T 城.T ...
- BZOJ 3999 旅游
.......好长啊. #include<iostream> #include<cstdio> #include<cstring> #include<algo ...
- BZOJ 2157 旅游(动态树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2157 [题目大意] 支持修改边,链上查询最大值最小值总和,以及链上求相反数 [题解] ...
随机推荐
- iOS关于代码风格问题
cocoapods管理第三方库,详见cocoapods安装及使用 OC代码风格需要规范,所有第三方依赖需要用cocoapods管理.代码风格需要: 1. pod 'CodeFormatter', :g ...
- iOS中生成随机的UUID
+ (NSString *)uuidString { CFUUIDRef uuid_ref = CFUUIDCreate(NULL); CFStringRef uuid_string_ref= CFU ...
- 社区发现SLPA算法
社区(community)定义:同一社区内的节点与节点之间关系紧密,而社区与社区之间的关系稀疏. 设图G=G(V,E),所谓社区发现是指在图G中确定nc(>=1)个社区C={C1,C2,..., ...
- 再也不怕aop的原理了
1 aop是什么 java的核心思想是面向对象,aop是面向切面编程.是对面向对象的一个补充,简单通俗的理解下aop,假设我们上楼梯,我的目标是三楼,我直接朝我的三楼直接过去,但是我可以在二楼的时候去 ...
- Github如何在本地创建一个空的仓库
1.在任意地方创建文件夹,并进入该文件夹: 2.通过git init命令把该文件夹变成Git可管理的仓库: 3.该文件夹里会多了个.git文件夹,它是Git用来跟踪和管理版本库的: 4.这时候手动把项 ...
- JS正则表达式端口号,IP地址
端口号:65535 正则:/^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6 ...
- 用AndroidSDK中的Face Detector实现人脸识别
很多手机图片管理应用都开始集成人脸识别功能.一提到人脸识别,模式识别,滤波,BlahBlah 一堆复杂的技术名字戳入脑海中,立刻觉得这玩意儿没法碰,太玄乎了.其实Android SDK从1.0版本中( ...
- Linux下which命令使用详解(转)
我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索: which 查看可执行文件的位置. whereis 查看文件的位置. locate 配合数据库查看文件位置. f ...
- wap webapp app区别
“手机WAP版网站”.“手机触屏版网站”.“手机APP应用软件”: wap webapp app区别 电脑版:台式机或者笔记本访问,兼容各个浏览器: Wap版:用于传统智能手机,屏幕小,适合使用手机键 ...
- [中英对照]The sysfs Filesystem | sysfs文件系统
The sysfs Filesystem | sysfs文件系统 Abstract | 摘要 sysfs is a feature of the Linux 2.6 kernel that allow ...