P1505 [国家集训队]旅游

题目描述

\(\tt{Ray}\) 乐忠于旅游,这次他来到了\(T\)城。\(T\)城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,\(T\) 城的任意两个景点之间有且只有一条路径。换句话说, \(T\) 城中只有 \(N − 1\) 座桥。

\(\tt{Ray}\) 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度\(w\),也就是说,\(\tt{Ray}\) 经过这座桥会增加\(w\)的愉悦度,这或许是正的也可能是负的。有时,\(\tt{Ray}\) 看待同一座桥的心情也会发生改变。

现在,\(\tt{Ray}\) 想让你帮他计算从\(u\)景点到\(v\)景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。

输入输出格式

输入格式:

输入的第一行包含一个整数\(N\),表示\(T\)城中的景点个数。景点编号为 \(0\dots N − 1\)。

接下来 \(N − 1\) 行,每行三个整数\(u\)、\(v\) 和\(w\),表示有一条 \(u\) 到 \(v\),使 \(\tt{Ray}\) 愉悦度增加 \(w\) 的桥。桥的编号为\(1\dots N − 1\)。\(|w| \le 1000\)。 输入的第 \(N + 1\) 行包含一个整数\(M\),表示 \(\tt{Ray}\) 的操作数目。

接下来有 \(M\) 行,每行描述了一个操作,操作有如下五种形式:

  • C i w,表示\(\tt{Ray}\)对于经过第 \(i\) 座桥的愉悦度变成了 \(w\)。

  • N u v,表示\(\tt{Ray}\) 对于经过景点 \(u\) 到 \(v\) 的路径上的每一座桥的愉悦度都变成原来的相反数。

  • SUM u v,表示询问从景点 \(u\) 到 \(v\) 所获得的总愉悦度。

  • MAX u v,表示询问从景点 \(u\) 到 \(v\) 的路径上的所有桥中某一座桥所提供的最大愉悦度。

  • MIN u v,表示询问从景点 \(u\) 到 \(v\) 的路径上的所有桥中某一座桥所提供的最小愉悦度。

测试数据保证,任意时刻,\(\tt{Ray}\) 对于经过每一座桥的愉悦度的绝对值小于等于\(1000\)。

输出格式:

对于每一个询问(操作\(S\)、\(MAX\)和\(MIN\)),输出答案。


树链剖分模板题,挂了好多个小时简直自闭了。

奇怪的错误点:

  1. read()没读负数,最开始忘记生成负数据了一直拍不出来
  2. 若前向星的边的编号除2得到原始编号,应该从2开始编号,随机生成树的时候没打乱边的顺序没拍出来。

Code:

#include <cstdio>
#include <cctype>
const int N=2e5+10;
int head[N],to[N<<1],edge[N<<1],Next[N<<1],cnt=1;
void add(int u,int v,int w)
{
to[++cnt]=v,edge[cnt]=w,Next[cnt]=head[u],head[u]=cnt;
to[++cnt]=u,edge[cnt]=w,Next[cnt]=head[v],head[v]=cnt;
}
int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') f=-f;c=getchar();}
while(isdigit(c)) {x=x*10+c-'0';c=getchar();}
return x*f;
}
int num[N],dtp[N],ha[N],top[N],f[N],dfn[N],dep[N],siz[N],ws[N],dfs_clock=-1;
void dfs1(int now)
{
siz[now]=1;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(v!=f[now])
{
f[v]=now,dep[v]=dep[now]+1,num[i>>1]=v,dtp[v]=i;
dfs1(v);
siz[now]+=siz[v];
if(siz[v]>siz[ws[now]]) ws[now]=v;
}
}
}
void dfs2(int now,int anc)
{
dfn[now]=++dfs_clock;
ha[dfs_clock]=now;
top[now]=anc;
if(ws[now]) dfs2(ws[now],anc);
for(int i=head[now];i;i=Next[i])
if(!dfn[to[i]]&&to[i]!=1)
dfs2(to[i],to[i]);
}
int sum[N<<2],mx[N<<2],mi[N<<2],tag[N<<2],tot,tmp;
int n,m;char op[6];
#define ls id<<1
#define rs id<<1|1
int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
void swap(int &x,int &y){tmp=x,x=y,y=tmp;}
void updata(int id)
{
mx[id]=max(mx[ls],mx[rs]);
mi[id]=min(mi[ls],mi[rs]);
sum[id]=sum[ls]+sum[rs];
}
void build(int id,int l,int r)
{
if(l==r)
{
sum[id]=mx[id]=mi[id]=edge[dtp[ha[l]]];
return;
}
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
updata(id);
}
void rev(int id)
{
mx[id]=-mx[id],mi[id]=-mi[id];
swap(mx[id],mi[id]);
}
void pushdown(int id)
{
if(tag[id])
{
sum[ls]=-sum[ls],sum[rs]=-sum[rs];
rev(ls),rev(rs);
tag[ls]^=1,tag[rs]^=1;
tag[id]^=1;
}
}
void change(int id,int l,int r,int p,int d)
{
if(l==r)
{
mx[id]=mi[id]=sum[id]=d;
return;
}
pushdown(id);
int mid=l+r>>1;
if(p<=mid) change(ls,l,mid,p,d);
else change(rs,mid+1,r,p,d);
updata(id);
}
void Reverse(int id,int L,int R,int l,int r)
{
if(L==l&&R==r)
{
tag[id]^=1,sum[id]=-sum[id],rev(id);
return;
}
pushdown(id);
int Mid=L+R>>1;
if(r<=Mid) Reverse(ls,L,Mid,l,r);
else if(l>Mid) Reverse(rs,Mid+1,R,l,r);
else Reverse(ls,L,Mid,l,Mid),Reverse(rs,Mid+1,R,Mid+1,r);
updata(id);
}
void modify(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]>=dep[top[y]])
{
Reverse(1,1,n,dfn[top[x]],dfn[x]);
x=f[top[x]];
}
else
{
Reverse(1,1,n,dfn[top[y]],dfn[y]);
y=f[top[y]];
}
}
if(dep[x]<dep[y]) swap(x,y);
if(x!=y) Reverse(1,1,n,dfn[y]+1,dfn[x]);
}
int querys(int id,int L,int R,int l,int r)
{
if(l==L&&r==R) return sum[id];
pushdown(id);
int Mid=L+R>>1;
if(r<=Mid) return querys(ls,L,Mid,l,r);
else if(l>Mid) return querys(rs,Mid+1,R,l,r);
else return querys(ls,L,Mid,l,Mid)+querys(rs,Mid+1,R,Mid+1,r);
}
int querysum(int x,int y)
{
int s=0;
while(top[x]!=top[y])
{
if(dep[top[x]]>=dep[top[y]])
{
s+=querys(1,1,n,dfn[top[x]],dfn[x]);
x=f[top[x]];
}
else
{
s+=querys(1,1,n,dfn[top[y]],dfn[y]);
y=f[top[y]];
}
}
if(dep[x]<dep[y]) swap(x,y);
if(x!=y) s+=querys(1,1,n,dfn[y]+1,dfn[x]);
return s;
}
int querymi(int id,int L,int R,int l,int r)
{
if(l==L&&r==R) return mi[id];
pushdown(id);
int Mid=L+R>>1;
if(r<=Mid) return querymi(ls,L,Mid,l,r);
else if(l>Mid) return querymi(rs,Mid+1,R,l,r);
else return min(querymi(ls,L,Mid,l,Mid),querymi(rs,Mid+1,R,Mid+1,r));
}
int querymin(int x,int y)
{
int s=N;
while(top[x]!=top[y])
{
if(dep[top[x]]>=dep[top[y]])
{
s=min(s,querymi(1,1,n,dfn[top[x]],dfn[x]));
x=f[top[x]];
}
else
{
s=min(s,querymi(1,1,n,dfn[top[y]],dfn[y]));
y=f[top[y]];
}
}
if(dep[x]<dep[y]) swap(x,y);
if(x!=y) s=min(s,querymi(1,1,n,dfn[y]+1,dfn[x]));
return s;
}
int querymx(int id,int L,int R,int l,int r)
{
if(l==L&&r==R) return mx[id];
pushdown(id);
int Mid=L+R>>1;
if(r<=Mid) return querymx(ls,L,Mid,l,r);
else if(l>Mid) return querymx(rs,Mid+1,R,l,r);
else return max(querymx(ls,L,Mid,l,Mid),querymx(rs,Mid+1,R,Mid+1,r));
}
int querymax(int x,int y)
{
int s=-N;
while(top[x]!=top[y])
{
if(dep[top[x]]>=dep[top[y]])
{
s=max(s,querymx(1,1,n,dfn[top[x]],dfn[x]));
x=f[top[x]];
}
else
{
s=max(s,querymx(1,1,n,dfn[top[y]],dfn[y]));
y=f[top[y]];
}
}
if(dep[x]<dep[y]) swap(x,y);
if(x!=y) s=max(s,querymx(1,1,n,dfn[y]+1,dfn[x]));
return s;
}
#define rep(i,a,b) for(int i=a;i<=b;i++)
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
n=read();
int u,v,w;rep(i,1,(n-1)) u=read()+1,v=read()+1,w=read(),add(u,v,w);
dep[1]=1,dfs1(1),dfs2(1,1);
m=read();
build(1,1,--n);
rep(i,1,m)
{
scanf("%s",op);
u=read()+1,v=read()+1;
if(op[0]=='C') change(1,1,n,dfn[num[u-1]],v-1);
else if(op[0]=='N') modify(u,v);
else if(op[0]=='S') printf("%d\n",querysum(u,v));
else if(op[1]=='A') printf("%d\n",querymax(u,v));
else printf("%d\n",querymin(u,v));
}
return 0;
}

2018.11.5

洛谷 P1505 [国家集训队]旅游 解题报告的更多相关文章

  1. 洛谷 P1505 [国家集训队]旅游 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1505 [国家集训队]旅游 题目描述 Ray 乐 ...

  2. 2018.06.29 洛谷P1505 [国家集训队]旅游(树链剖分)

    旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有 ...

  3. 洛谷P1505 [国家集训队]旅游

    题目描述 \(Ray\) 乐忠于旅游,这次他来到了\(T\) 城.\(T\) 城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,\(T ...

  4. 洛谷P1505 [国家集训队]旅游(树剖+线段树)

    传送门 这该死的码农题…… 把每一条边变为它连接的两个点中深度较浅的那一个,然后就是一堆单点修改/路径查询,不讲了 这里就讲一下怎么搞路径取反,只要打一个标记就好了,然后把区间和取反,最大最小值交换然 ...

  5. [洛谷]P1505 [国家集训队]旅游

    题目链接: 传送门 题目分析: 树剖板,支持单点修改,区间取反,区间求最大值/最小值/和 区间取反取两次等于没取,维护一个\(rev\ tag\),每次打标记用\(xor\)打,记录是否需要翻转,\( ...

  6. 模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)

    洛谷P2634 [国家集训队]聪聪可可 静态点分治 一开始还以为要把分治树建出来……• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法.• A:朴素做法,直接找重心, ...

  7. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  8. 洛谷 P1852 [国家集训队]跳跳棋 解题报告

    P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...

  9. 洛谷 P1407 [国家集训队]稳定婚姻 解题报告

    P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...

随机推荐

  1. redux devtools调试工具

    项目安装: npm install redux-devtools-extension -dev 谷歌搜索 Redux DevTools 安装: 使用: 主要用到state&Dispatcher ...

  2. 浅析JVM内存区域及垃圾回收

    一.JVM简介 JVM,全称Java Virtual Machine,即Java虚拟机.以Java作为编程语言所编写的应用程序都是运行在JVM上的.JVM是一种用于计算设备的规范,它是一个虚构出来的计 ...

  3. Qt-QPalette-调色板学习

    已经很久没有更新博客了,一是因为换了公司,完全是断网开发了,没有时间来写博客,最主要的就是温水煮青蛙,自己在舒适的环境中越来越懒了,最近打算强制自己更新一波.不知道能坚持多久.由于目前没有具体的Qt项 ...

  4. Kotlin Android Extensions: 与 findViewById 说再见 (KAD 04) -- 更新版

    作者:Antonio Leiva 时间:Aug 16, 2017 原文链接:https://antonioleiva.com/kotlin-android-extensions/ 在 Kotlin1. ...

  5. 腾讯云API弹性公网IP踩坑

    由于自己管理的云服务器数量比较多,时不时需要更换IP,在管理台上一下下点击,实在浪费时间,于是就想到了通过API调用的方式,将更换IP一系列动作,全部集成到Python代码里面,实现一行命令,完成IP ...

  6. [转]JS私有化的实现——稳妥构造函数

    所谓稳妥对象, 指的是没有公共属性, 而且其方法也不引用this的对象.稳妥对象函数遵循与寄生构造函数类似的模式, 但有两点不同: 一是新创建对象的实例方法不引用this: 二是不使用new操作符调用 ...

  7. Windowserver2012部署always on

    1.首先,安装域环境 IP设置 域服务安装 如果建立域配置时出现 administrator账户密码不符合要求错误: cmd运行命令: net user administrator /password ...

  8. 试用Markdown来写东西

    试用Markdown来写东西 前言 之前有过一段时间的写东西的习惯,但是后来因为各种原因(主要是因为自己懒惰拖延),所以一直没有写,现在想再开始写,目的很明确,就是发现很多时候,写作能够很好的练习自己 ...

  9. smartgit 使用

    合并分支

  10. HDU 3268/POJ 3835 Columbus’s bargain(最短路径+暴力枚举)(2009 Asia Ningbo Regional)

    Description On the evening of 3 August 1492, Christopher Columbus departed from Palos de la Frontera ...