[BZOJ2959]长跑——新技能:LCT+缩圈
[BZOJ2959]长跑
试题描述
某校开展了同学们喜闻乐见的阳光长跑活动。为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动。一时间操场上熙熙攘攘,摩肩接踵,盛况空前。
为了让同学们更好地监督自己,学校推行了刷卡机制。
学校中有n个地点,用1到n的整数表示,每个地点设有若干个刷卡机。
有以下三类事件:
1、修建了一条连接A地点和B地点的跑道。
2、A点的刷卡机台数变为了B。
3、进行了一次长跑。问一个同学从A出发,最后到达B最多可以刷卡多少次。具体的要求如下:
当同学到达一个地点时,他可以在这里的每一台刷卡机上都刷卡。但每台刷卡机只能刷卡一次,即使多次到达同一地点也不能多次刷卡。
为了安全起见,每条跑道都需要设定一个方向,这条跑道只能按照这个方向单向通行。最多的刷卡次数即为在任意设定跑道方向,按照任意路径从A地点到B地点能刷卡的最多次数。
输入
输入的第一行包含两个正整数n,m,表示地点的个数和操作的个数。
第二行包含n个非负整数,其中第i个数为第个地点最开始刷卡机的台数。
接下来有m行,每行包含三个非负整数P,A,B,P为事件类型,A,B为事件的两个参数。
最初所有地点之间都没有跑道。
每行相邻的两个数之间均用一个空格隔开。表示地点编号的数均在1到n之间,每个地点的刷卡机台数始终不超过10000,P=1,2,3。
输出
输出的行数等于第3类事件的个数,每行表示一个第3类事件。如果该情况下存在一种设定跑道方向的方案和路径的方案,可以到达,则输出最多可以刷卡的次数。如果A不能到达B,则输出-1。
输入示例
输出示例
-
-
数据规模及约定
对于100%的数据,m<=5n,任意时刻,每个地点的刷卡机台数不超过10000。N<=1.5×105
题解
注意这道题目有双连通分量时是可以设计一种方案跑遍整个双连通分量的,因此简单的LCT维护时不行的,要用到缩圈。
所谓的缩圈即出现一个圈就把它缩成一个点,这个新点的权值等于该圈上所有原来节点权值之和。遍历一遍就可以实现了。
令a = 圈中节点个数,每次缩圈的复杂度为O(a),于此同时整个图的节点个数减少了(a-1)个点,所以总缩圈时间复杂度是O(n)的,那么总时间复杂度为O(n + mlogn)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *tail;
inline char Getchar() {
if(Head == tail) {
int l = fread(buffer, 1, BufferSize, stdin);
tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 150010
#define maxm 750010
#define oo 2147483647
int n, q; int pa[maxn], pc[maxn];
int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); }
int findc(int x) { return x == pc[x] ? x : pc[x] = findc(pc[x]); } int fa[maxn], ch[maxn][2], sumv[maxn], val[maxn], A[maxn];
bool rev[maxn];
bool isroot(int u) { return ch[findc(fa[u])][0] != u && ch[findc(fa[u])][1] != u; }
void maintain(int u) {
int lc = ch[u][0], rc = ch[u][1];
sumv[u] = sumv[lc] + val[u] + sumv[rc];
return ;
}
void pushdown(int u) {
int &lc = ch[u][0], &rc = ch[u][1];
if(rev[u]) {
rev[u] = 0; swap(lc, rc);
rev[lc] ^= 1; rev[rc] ^= 1;
}
return ;
}
void rotate(int u) {
int y = findc(fa[u]), z = findc(fa[y]), l = 0, r = 1;
if(ch[y][1] == u) swap(l, r);
if(!isroot(y)) ch[z][ch[z][1]==y] = u;
fa[u] = z; fa[y] = u; fa[ch[u][r]] = y;
ch[y][l] = ch[u][r]; ch[u][r] = y;
maintain(y); maintain(u);
return ;
}
int S[maxn], top;
void splay(int u) {
bool flag = 0;
S[++top] = u;
for(int t = u; !isroot(t); t = findc(fa[t])) S[++top] = findc(fa[t]);
while(top) pushdown(S[top--]);
if(flag) putchar('\n');
while(!isroot(u)) {
int y = findc(fa[u]), z = findc(fa[y]);
if(!isroot(y)) {
if((ch[y][0] == u) ^ (ch[z][0] == y)) rotate(u);
else rotate(y);
}
rotate(u);
}
return ;
}
void access(int u) {
for(int t = 0; u; u = fa[u]) {
u = findc(u);
splay(u); ch[u][1] = t; maintain(u); t = u;
}
return ;
}
void makeroot(int u) {
access(u); splay(u); rev[u] ^= 1;
return ;
}
void link(int a, int b) {
makeroot(a); fa[a] = b;
return ;
}
void split(int a, int b) {
makeroot(b); access(a); splay(a);
return ;
} void dfs(int u, int v) {
if(!u) return ;
pushdown(u);
pc[u] = v;
if(u != v) val[v] += val[u];
dfs(ch[u][0], v); dfs(ch[u][1], v);
ch[u][0] = ch[u][1] = 0;
return ;
} int main() {
n = read(); q = read();
for(int i = 1; i <= n; i++) A[i] = val[i] = read(), pa[i] = pc[i] = i;
while(q--) {
int p = read(), a = read(), b = read();
if(p == 1) {
a = findc(a); b = findc(b); if(a == b) continue;
int u = findset(a), v = findset(b);
if(u != v) pa[v] = u, link(a, b);
else {
split(a, b); dfs(a, a); maintain(a);
}
}
if(p == 2) {
int c = findc(a);
splay(c);
val[c] += b - A[a]; A[a] = b;
maintain(c);
}
if(p == 3) {
a = findc(a); b = findc(b);
int u = findset(a), v = findset(b);
if(u != v) puts("-1");
else split(a, b), printf("%d\n", sumv[a]);
}
} return 0;
}
[BZOJ2959]长跑——新技能:LCT+缩圈的更多相关文章
- 5332盛照宗 如何获取新技能+c语言学习调查
如何获取新技能+c语言学习调查 你有什么技能比大多人(超过90%以上)更好? 如果问我有没有什么技能比大多数人,并且是90%的人好,我还真不敢说有,因为世界上有70亿人,要比63亿人做的好才行啊.我也 ...
- 腾讯优测干货精选| 安卓开发新技能Get -常用必备小工具汇总
文/腾讯公司 陈江峰 优测小优有话说: 移动研发及测试干货哪里找?腾讯优测-优社区你值得拥有~ 开发同学们都知道,安卓开发路上会碰到很多艰难险阻,一不小心就被KO.这时候,没有新技能傍身怎么行?今天我 ...
- 20155332 如何获取新技能+c语言学习调查
如何获取新技能+c语言学习调查 你有什么技能比大多人(超过90%以上)更好? 如果问我有没有什么技能比大多数人,并且是90%的人好,我还真不敢说有,因为世界上有70亿人,要比63亿人做的好才行啊.我也 ...
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- [站点推荐]001.学习新技能的37个最佳网站(The 37 Best Websites To Learn Something New)
忘了过于褒奖的学校.整天呆在拥挤的教室而效果却差得可怜.这些网站和应用涵盖了科学.艺术和技术的无数话题.它们可以教会你实践练习任何技能,从制作豆 沙到用 node.js 开发 app,而且它们都是免费 ...
- Git新技能-stash操作
最近开发的工期非常紧迫,一直在忙各种杂七杂八的事情,负责人都还没有创建好测试环境, 所以代码也不能部署.可是项目经理催促开发进度又催得很急,新的开发需求必须在指定的时间内 完成,我们只得想办法去克服困 ...
- BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)
题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...
- bzoj2959: 长跑(LCT+并查集)
题解 动态树Link-cut tree(LCT)总结 LCT常数大得真实 没有环,就是\(lct\)裸题吧 有环,我们就可以绕环转一圈,缩点 怎么搞? 当形成环时,把所有点的值全部加到一个点上,用并查 ...
- bzoj2959: 长跑 LCT+并查集+边双联通
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2959 题解 调了半天,终于调完了. 显然题目要求是求出目前从 \(A\) 到 \(B\) 的可 ...
随机推荐
- c# 6.0新特性(一)
写在前面 接近年底了,基本上没什么活了,就学点新东西,就想着了解下c# 6.0的新特性.在code project上看到了一篇不错的文章,就准备翻译一下,顺便照着学习学习.废话不多说,直奔主题. 原文 ...
- go语言指针符号的*和&
先看一段代码 先放一段代码,人工运行一下,看看自己能做对几题? package main import "fmt" func main() { var a int = 1 var ...
- 传说中的WeixinJSBridge和微信rest接口
直接上图,金山的APP“微信导航”,从界面上看有粉丝数等关键数据,实现了直接关注功能,莫不是rest接口?这江湖是大佬们的江湖,小喽啰只有眼馋的份咯. 很早就听说过WeixinJSBridge,不过官 ...
- C基础--C语言的数组
数组的定义: 一.正确写法: 1.int ages[5]--定义了一个5个长度的int类型的数组 2.int ages[]={1,2,3,4,5};--定义了一个5个长度的int类型的数组,并且初始化 ...
- js简单的工厂模式
<!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...
- 字符串转json
function str2json(str) { var arr = str.split('.'), json = {}, _this = json; if (!json[arr[0]]) json[ ...
- [Asp.net mvc] Asp.net mvc Kendo UI Grid的使用(四)
有段时间没写博客了,工作状态比较忙,抽空继续总结下Grid的使用,这次主要介绍模板以及其他官网介绍不详尽的使用方法.先Show出数据,然后讲解下.后台代码: public ActionResult O ...
- jQuery技术交流资料
jQuery技术交流资料https://www.zybuluo.com/jikeytang/note/65371
- POJ2492 A Bug's Life
Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 33833 Accepted: 11078 Description Ba ...
- mysql语句分析
explain的每个输出行提供一个表的相关信息,并且每个行包括下面的列: 1,id select识别符.这是select的查询序列号.2,select_type 可以为一下任何一种类型simple ...