洛谷 P1505 BZOJ 2157 [国家集训队]旅游
- Time limit 10000 ms
- Memory limit 265216 kB
- OS Linux
吐槽
又浪费一个下午……区间乘-1之后,最大值和最小值更新有坑。新的最大值是原来最小值乘-1,新的最小值是原来最大值乘-1。
没脸见人了
树链剖分,但这题的权值在边上不在点上,那我们只需要在dfs过程中把边权搞到下方的点上,然后两点间各种操作时,不对两点LCA进行操作就好(见代码里一串/
)
听说LCT处理这个更擅长,留坑
源代码
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
const int MAXN=2e4+5;
int n,q;
struct Edge{
int nxt,to,w,id;
}e[MAXN<<1];
int head[MAXN],cnt=1;
inline void add(int u,int v,int w,int id)
{
e[cnt]={head[u],v,w,id};
head[u]=cnt++;
e[cnt]={head[v],u,w,id};
head[v]=cnt++;
}
int bridge[MAXN];//用桥的id查询点
struct Tree{
int w;
int fa,dep,sz,wson;
int id,top;
}t[MAXN];
void dfs1(int u,int fa,int eid)
{
t[u].w=e[eid].w;
bridge[e[eid].id]=u;
t[u].fa=fa;
t[u].dep=t[t[u].fa].dep+1;
t[u].sz=1;
int mxson=-1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(fa==v) continue;
dfs1(v,u,i);
int temp=t[v].sz;
if(temp>mxson)
{
t[u].wson=v;
mxson=temp;
}
t[u].sz+=temp;
}
}
int a[MAXN],id=1;
void dfs2(int u,int top)
{
t[u].top=top;
t[u].id=id;
a[id]=t[u].w;
id++;
if(t[u].sz==1) return;
dfs2(t[u].wson,top);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==t[u].wson||v==t[u].fa) continue;
dfs2(v,v);
}
}
struct Segtree{
int sum;
int mx;
int mn;
bool lazy;//乘-1的
}s[MAXN<<2];
inline void pushup(int x)
{
s[x].sum=s[x<<1].sum+s[x<<1|1].sum;
s[x].mx=std::max(s[x<<1].mx,s[x<<1|1].mx);
s[x].mn=std::min(s[x<<1].mn,s[x<<1|1].mn);
}
void build(int x,int l,int r)
{
if(l==r)
{
s[x]={a[l],a[l],a[l],0};
return;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
inline void pushdown(int x)
{
if(!s[x].lazy) return;
s[x<<1].lazy=!s[x<<1].lazy;
int temp=s[x<<1].mx;
s[x<<1].mx=-s[x<<1].mn;
s[x<<1].mn=-temp;
s[x<<1].sum*=-1;
s[x<<1|1].lazy=!s[x<<1|1].lazy;
temp=s[x<<1|1].mx;
s[x<<1|1].mx=-s[x<<1|1].mn;
s[x<<1|1].mn=-temp;
s[x<<1|1].sum*=-1;
s[x].lazy=0;
}
void mul(int x,int l,int r,int ql,int qr)//区间乘-1
{
if(ql<=l&&r<=qr)
{
s[x].lazy=!s[x].lazy;
int temp=s[x].mx;
s[x].mx=-s[x].mn;
s[x].mn=-temp;
s[x].sum*=-1;
return;
}
pushdown(x);
int mid=l+r>>1;
if(ql<=mid) mul(x<<1,l,mid,ql,qr);
if(qr>mid) mul(x<<1|1,mid+1,r,ql,qr);
pushup(x);
}
void change(int x,int l,int r,int pos,int k)
{
if(l==r)
{
s[x].mn=k;
s[x].mx=k;
s[x].sum=k;
return;
}
pushdown(x);
int mid=l+r>>1;
if(pos<=mid) change(x<<1,l,mid,pos,k);
else change(x<<1|1,mid+1,r,pos,k);
pushup(x);
}
int quesum(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return s[x].sum;
int mid=l+r>>1;
int ans=0;
pushdown(x);
if(ql<=mid) ans+=quesum(x<<1,l,mid,ql,qr);
if(qr>mid) ans+=quesum(x<<1|1,mid+1,r,ql,qr);
return ans;
}
int quemx(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return s[x].mx;
int mid=l+r>>1;
int ans=-99999999;
pushdown(x);
if(ql<=mid) ans=std::max(quemx(x<<1,l,mid,ql,qr),ans);
if(qr>mid) ans=std::max(quemx(x<<1|1,mid+1,r,ql,qr),ans);
return ans;
}
int quemn(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return s[x].mn;
int mid=l+r>>1;
int ans=99999999;
pushdown(x);
if(ql<=mid) ans=std::min(quemn(x<<1,l,mid,ql,qr),ans);
if(qr>mid) ans=std::min(quemn(x<<1|1,mid+1,r,ql,qr),ans);
return ans;
}
void optn(int x,int y)
{
while(t[x].top!=t[y].top)
{
if(t[t[x].top].dep<t[t[y].top].dep)
std::swap(x,y);
mul(1,1,n,t[t[x].top].id,t[x].id);
x=t[t[x].top].fa;
}
if(x==y) return;
if(t[x].id>t[y].id) std::swap(x,y);
mul(1,1,n,t[x].id+1,t[y].id);///////////////////////////////////////////////////////////////////
}
int optsum(int x,int y)
{
int ans=0;
while(t[x].top!=t[y].top)
{
if(t[t[x].top].dep<t[t[y].top].dep) std::swap(x,y);
ans+=quesum(1,1,n,t[t[x].top].id,t[x].id);
x=t[t[x].top].fa;
}
if(x==y) return ans;
if(t[x].id>t[y].id) std::swap(x,y);
ans+=quesum(1,1,n,t[x].id+1,t[y].id);
return ans;
}
int optmx(int x,int y)
{
int ans=-99999999;
while(t[x].top!=t[y].top)
{
if(t[t[x].top].dep<t[t[y].top].dep) std::swap(x,y);
ans=std::max(ans,quemx(1,1,n,t[t[x].top].id,t[x].id));
x=t[t[x].top].fa;
}
if(x==y) return ans;
if(t[x].id>t[y].id) std::swap(x,y);
ans=std::max(ans,quemx(1,1,n,t[x].id+1,t[y].id));
return ans;
}
int optmn(int x,int y)
{
int ans=99999999;
while(t[x].top!=t[y].top)
{
if(t[t[x].top].dep<t[t[y].top].dep) std::swap(x,y);
ans=std::min(ans,quemn(1,1,n,t[t[x].top].id,t[x].id));
x=t[t[x].top].fa;
}
if(x==y) return ans;
if(t[x].id>t[y].id) std::swap(x,y);
ans=std::min(ans,quemn(1,1,n,t[x].id+1,t[y].id));
return ans;
}
int main()
{
//freopen("test.in","r",stdin);
scanf("%d",&n);
for(int i=1,u,v,w;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u+1,v+1,w,i);
}
dfs1(1,0,0);
dfs2(1,1);
build(1,1,n);
scanf("%d",&q);
//for(int i=1;i<n;i++)
//printf("%d ",bridge[i]);
//puts("");
while(q--)
{
char opt[10];
int u,v;
scanf("%s%d%d",opt,&u,&v);
if(opt[0]=='C')
change(1,1,n,t[bridge[u]].id,v);
else if(opt[0]=='N') optn(u+1,v+1);
else if(opt[0]=='S')
printf("%d\n",optsum(u+1,v+1));
else if(opt[1]=='A')
printf("%d\n",optmx(u+1,v+1));
else printf("%d\n",optmn(u+1,v+1));
}
return 0;
}
洛谷 P1505 BZOJ 2157 [国家集训队]旅游的更多相关文章
- 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】
P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...
- 【洛谷】1494:[国家集训队]小Z的袜子【莫队】
P1494 [国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… ...
- 洛谷P1903 数颜色 [国家集训队] 莫队
正解:带修莫队 解题报告: 可以理解为引入时间参数,然后就是有了仨参数,关于这个修改同样的是,如果时间是相同的,不用搞,如果时间不相同做一下时光倒流/时光推移就成嘛 但是肯定既然这样的话,按照原来的s ...
- 题解 洛谷P1903/BZOJ2120【[国家集训队]数颜色 / 维护队列】
对于不会树套树.主席树的本蒟蒻,还是老老实实的用莫队做吧.... 其实这题跟普通莫队差不了多远,无非就是有了一个时间,当我们按正常流程排完序后,按照基本的莫队来,做莫队时每次循环对于这一次操作,我们在 ...
- 题解 洛谷P1501/BZOJ2631【[国家集训队]Tree II】
Link-Cut-Tree 的懒标记下传正确食用方法. 我们来逐步分析每一个操作. 1:+ u v c:将u到v的路径上的点的权值都加上自然数c; 解决方法: 很显然,我们可以 split(u,v) ...
- 洛谷 P1505 [国家集训队]旅游 解题报告
P1505 [国家集训队]旅游 题目描述 \(\tt{Ray}\) 乐忠于旅游,这次他来到了\(T\)城.\(T\)城是一个水上城市,一共有 \(N\) 个景点,有些景点之间会用一座桥连接.为了方便游 ...
- 树链剖分【洛谷P1505】 [国家集训队]旅游
P1505 [国家集训队]旅游 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城 ...
- 洛谷 P1505 [国家集训队]旅游 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1505 [国家集训队]旅游 题目描述 Ray 乐 ...
- luoguP1505 [国家集训队]旅游(真的毒瘤)
luogu P1505 [国家集训队]旅游 题目 #include<iostream> #include<cstdio> #include<cstdlib> #in ...
随机推荐
- Java并发ReadWriteLock接口
java.util.concurrent.locks.ReadWriteLock接口允许一次读取多个线程,但一次只能写入一个线程. 读锁 - 如果没有线程锁定ReadWriteLock进行写入,则多线 ...
- Java学习开发第三阶段总结
第三阶段的学习总结: 在这次学习我学习了面向对象和封装的知识. ①类的定义 package day01; public class student { //成员变量 String name; //姓名 ...
- PERCONA-TOOLKIT 安装 使用
1.基于MySQL主从环境 可以参考https://www.cnblogs.com/xianglei_/p/12068241.html 上传rpm包 并安装 1 2 cd /usr/local/src ...
- ORACLE 使用通配符进行字符串截取
ORACLE 使用通配符进行字符串截取 select regexp_substr('aa--a(1-23),b---b(32---1)','[^(,)]+',1,1) as col1, regexp_ ...
- oracle group by rollup实现小计、合计
SQL合计汇总实现数据N+1条显示: 注意group by rollup((ename, job, empno))!!! select decode(grouping(ename) + groupin ...
- 【6.28校内test】T2 【音乐会】二重变革
[音乐会]二重变革[题目链接] T2其实是一道数学题,因为你看: 2MB??一共就可以存下个int,然鹅再看数据范围: 那么大是稳稳的不是TLE就是MLE了,所以肯定是数学题,而且是只需要存很少数据的 ...
- HDU 3182 ——A Magic Lamp(思维)
Description Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie in the lam ...
- Python文件的几种读写方式
1). "w "写模式,它是不能读的,如果用w模式打开一个已经存在的文件,会清空以前的文件内容,重新写 "w+ "是读写内容,只要沾上w,肯定会清空原来的文件2 ...
- async 异步抓取 花瓣网高清大图 30s爬取500张
废话 不多说,直接上代码,不懂得看注释 先安装 pip install aiohttp "异步抓取花瓣网图片" # pip install aiohttp import requ ...
- 机器学习及scikit-learn
一.机器学习以及scikit-learn 1. 机器学习基本步骤: (1)定义一系列函数 => (2)定义函数的优劣 => (3)选择最优函数 2.什么是scikit-learn ...