[清华集训2016]温暖会指引我们前行——LCT+最大生成树
题目链接:
题目大意:有$n$个点$m$次操作,每次操作分为三种:1、在$u,v$两点之间连接一条编号为$id$,长度为$l$,温度为$t$的边。2、查询从$u$到$v$的最温暖的路径长度(定义最温暖的路径为将路径上的边按温度从小到大排序后字典序尽可能大)。3、将编号为$id$的边长度修改为$l$。
仔细读题发现题目中说的字典序其实就是使路径上的边都尽可能大。
那么最优方案一定就是走最大生成树上的边咯。
用LCT动态维护最大生成树。
当新加入边两端点不连通时直接连接,否则找到两点路径上的最小边,如果当前边比最小边大,那么将最小边删除并加入当前边。
在LCT上维护边的信息不好做,我们将每个边看成一个点。
例如编号为a的边连接x,y,那么就将a+n这个新建点分别连向x,y。
splay需要维护最小点权,点权和及最小点权点编号。
注意要将所有非边点的点权置成INF。
注意在find之后要将原树根旋到它所在splay的根,否则在uoj会被卡。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pr pair<int,int>
#define ll long long
using namespace std;
char ch[10];
int n,m;
int x,y,z,u,v;
struct miku
{
int x,y;
}a[600010];
int s[800010][2];
int mx[800010];
int mn[800010];
int r[800010];
int f[800010];
int w[800010];
int st[800010];
int sum[800010];
int t[800010];
int is_root(int rt)
{
return rt!=s[f[rt]][0]&&rt!=s[f[rt]][1];
}
int get(int rt)
{
return rt==s[f[rt]][1];
}
void pushup(int rt)
{
sum[rt]=sum[s[rt][0]]+sum[s[rt][1]]+w[rt];
mx[rt]=min(t[rt],min(mx[s[rt][0]],mx[s[rt][1]]));
if(mx[rt]==t[rt])
{
mn[rt]=rt;
}
else if(mx[rt]==mx[s[rt][0]])
{
mn[rt]=mn[s[rt][0]];
}
else
{
mn[rt]=mn[s[rt][1]];
}
}
void pushdown(int rt)
{
if(r[rt])
{
swap(s[rt][0],s[rt][1]);
r[s[rt][0]]^=1;
r[s[rt][1]]^=1;
r[rt]^=1;
}
}
void rotate(int rt)
{
int fa=f[rt];
int anc=f[fa];
int k=get(rt);
if(!is_root(fa))
{
s[anc][get(fa)]=rt;
}
s[fa][k]=s[rt][k^1];
f[s[fa][k]]=fa;
s[rt][k^1]=fa;
f[fa]=rt;
f[rt]=anc;
pushup(fa);
pushup(rt);
}
void splay(int rt)
{
int top=0;
st[++top]=rt;
for(int i=rt;!is_root(i);i=f[i])
{
st[++top]=f[i];
}
for(int i=top;i>=1;i--)
{
pushdown(st[i]);
}
for(int fa;!is_root(rt);rotate(rt))
{
if(!is_root(fa=f[rt]))
{
rotate(get(fa)==get(rt)?fa:rt);
}
}
}
void access(int rt)
{
for(int x=0;rt;x=rt,rt=f[rt])
{
splay(rt);
s[rt][1]=x;
pushup(rt);
}
}
void reverse(int rt)
{
access(rt);
splay(rt);
r[rt]^=1;
}
int find(int rt)
{
access(rt);
splay(rt);
while(s[rt][0])
{
rt=s[rt][0];
}
splay(rt);
return rt;
}
void link(int x,int y)
{
reverse(x);
f[x]=y;
}
void cut(int x,int y)
{
reverse(x);
access(y);
splay(y);
if(s[x][1]||f[x]!=y)
{
return ;
}
f[x]=s[y][0]=0;
pushup(y);
}
void change(int rt,int x)
{
w[rt]=x;
access(rt);
splay(rt);
}
int query(int x,int y)
{
reverse(x);
access(y);
splay(y);
return mn[y];
}
int ask(int x,int y)
{
reverse(x);
access(y);
splay(y);
return sum[y];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++)
{
t[i]=1000000007;
mx[i]=1000000007;
mn[i]=i;
w[i]=0;
sum[i]=0;
}
while(m--)
{
scanf("%s",ch);
if(ch[0]=='f')
{
scanf("%d%d%d%d%d",&x,&u,&v,&y,&z);
u++;
v++;
x++;
a[x].x=u;
a[x].y=v;
t[n+x]=y;
w[n+x]=z;
sum[n+x]=z;
mn[n+x]=n+x;
if(find(u)==find(v))
{
int id=query(u,v);
if(y>mx[id])
{
cut(id,a[id-n].x);
cut(id,a[id-n].y);
link(n+x,u);
link(n+x,v);
}
}
else
{
link(n+x,u);
link(n+x,v);
}
}
else if(ch[0]=='c')
{
scanf("%d%d",&x,&y);
x++;
change(n+x,y);
}
else
{
scanf("%d%d",&u,&v);
u++;
v++;
if(find(u)==find(v))
{
printf("%d\n",ask(u,v));
}
else
{
printf("-1\n");
}
}
}
}
[清华集训2016]温暖会指引我们前行——LCT+最大生成树的更多相关文章
- UOJ_274_[清华集训2016]温暖会指引我们前行_LCT
UOJ_274_[清华集训2016]温暖会指引我们前行_LCT 任务描述:http://uoj.ac/problem/274 本题中的字典序不同在于空串的字典序最大. 并且题中要求排序后字典序最大. ...
- [UOJ#274][清华集训2016]温暖会指引我们前行
[UOJ#274][清华集训2016]温暖会指引我们前行 试题描述 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一 ...
- UOJ274 [清华集训2016] 温暖会指引我们前行 【LCT】【最大生成树】
题目分析: 差评,最大生成树裸题.hack数据还卡常. 代码: #include<bits/stdc++.h> using namespace std; ; struct LCT{ ],d ...
- 【bzoj4736/uoj#274】[清华集训2016]温暖会指引我们前行 语文题+LCT
题目描述 http://uoj.ac/problem/274 题解 语文题+LCT 对于这种语文题建议还是自己读题好一些... 读懂题后发现:由于温度互不相同,最大生成树上的路径必须走(不走的话温度大 ...
- UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]
#274. [清华集训2016]温暖会指引我们前行 题意比较巧妙 裸lct维护最大生成树 #include <iostream> #include <cstdio> #incl ...
- 【UOJ274】【清华集训2016】温暖会指引我们前行 LCT
[UOJ274][清华集训2016]温暖会指引我们前行 任务描述 虽然小R住的宿舍楼早已来了暖气,但是由于某些原因,宿舍楼中的某些窗户仍然开着(例如厕所的窗户),这就使得宿舍楼中有一些路上的温度还是很 ...
- bzoj 4736 /uoj274【清华集训2016】温暖会指引我们前行 lct
[清华集训2016]温暖会指引我们前行 统计 描述 提交 自定义测试 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了 ...
- Uoj #274. 【清华集训2016】温暖会指引我们前行 LCT维护边权_动态最小生成树
Code: 行#include<bits/stdc++.h> #define ll long long #define maxn 1000000 #define inf 100000000 ...
- BZOJ 4736 温暖会指引我们前行 LCT+最优生成树+并查集
题目链接:http://uoj.ac/problem/274 题意概述: 没什么好概述的......概述了题意就知道怎么做了......我懒嘛 分析: 就是用lct维护最大生成树. 然后如果去UOJ上 ...
随机推荐
- CSP/NOIP 2019 游记
Day0 打牌 Day1 \(T1\) 没开\(ull\), 不知道有几分 \(T2\) \(N^2\)暴力+链, 没搞出树上做法, \(70\)分 \(T3\) 标准\(10\)分( 感觉今年省一稳 ...
- Git复习(十一)之常见命令用法
创建版本库 git init 进入一个文件,执行该命令此时目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了. ...
- nginx(五)- linux下安装nginx与配置
linux系统为Centos 64位 准备目录 [root@instance-3lm099to ~]# mkdir /usr/local/nginx [root@instance-3lm099to ~ ...
- HTML 5的革新之一:语义化标签一节元素标签。
摘至于:<HTML 5的革新——语义化标签(一)> HTML 5的革新之一:语义化标签一节元素标签. 在HTML 5出来之前,我们用div来表示页面章节,但是这些div都没有实际意义.(即 ...
- Java一些小例子
package com.example.demo; public class Solution { public static void main(String[] args) { func(); } ...
- 【异常】~/.bash_profile:source:44: no such file or directory: /usr/local/Cellar/nvm/0.34.0/nvm.sh
1 异常信息 /Users/zhangjin/.bash_profile:source:: no such file or directory: /usr/local/Cellar/nvm//nvm. ...
- yarn查看正在运行的任务列表
1 yarn application -list
- Python之路:进程、线程
目录 一.进程与线程区别 1.1 什么是线程 1.2 什么是进程 1.3 进程与线程的区别 二.Python GIL全局解释器锁 三.线程 3.1 threading模块 3.2 Join & ...
- jquery 在将对象作为参数传递的时候要转换成 JSON
不转换成JSON 会报错 Unexpected identifier 方法: JSON.stringify(对象)
- 【BZOJ2752】【Luogu P2221】 [HAOI2012]高速公路
不是很难的一个题目.正确思路是统计每一条边被经过的次数,但我最初由于习惯直接先上了一个前缀和再推的式子,导致极其麻烦难以写对而且会爆\(longlong\). 推导过程请看这里. #include & ...