[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\) 的可 ...
随机推荐
- ASP.NET服务器控件使用之MultiView和View
MultiView 控件是一组 View 控件的容器.使用它可定义一组 View 控件,其中每个 View 控件都包含子控件. 用 ActiveViewIndex 属性或SetActiveView 方 ...
- [BZOJ1211][HNOI2004]树的计数(Prufer序列)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1211 分析: 关于无根树的组合数学问题肯定想到Prufer序列,类似bzoj1005那 ...
- Javascript基础系列之(五)关键字和保留字 (keyword)
关键字不可以作为变量名或者函数名 break case catch continue default delete do else finally for function if in instanc ...
- jQuery基础之(四)jQuery创建DOM元素
利用DOM方法创建元素节点,通常要将document.createElement().document.createTextNode().appendChild()配合使用,十分麻烦. 而jQuery ...
- metaspolit 基础
在kali中使用metasploit,需要先开启PostgreSQL数据库服务和metasploit服务,然后就可以完整的利用msf数据库查询exploit和记录了.这一点比bt5要方便很多,所以现在 ...
- 某表含有N个字段超精简模糊查询方法
我们在做多个字段模糊查询时,是不是觉得非常麻烦?比如我要模糊查询某表多个字段存在某数据时,如下 select * from table where a like '%key%' or b like ...
- AtomicInteger源码分析
问题背景 最近在看LinkedBlockingQueue看到了其中的count使用AtomicInteger修饰,之前也看过AtomicInteger的一些解释,也是似懂非懂的,今天深入的了解了其实现 ...
- bzoj 3437 斜率优化DP
写题解之前首先要感谢妹子. 比较容易的斜率DP,设sum[i]=Σb[j],sum_[i]=Σb[j]*j,w[i]为第i个建立,前i个的代价. 那么就可以转移了. /**************** ...
- 【BZOJ-3172】单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2567 Solved: 1200[Submit][Status ...
- BZOJ3246 [Ioi2013]Dreaming
Description Serpent(水 蛇)生活的地方有N个水坑,编号为0,...,N - 1,有M条双向小路连接这些水坑.每两个水坑之间至多有一条路径(路径包含一条或多条小路)相互连接,有些水坑 ...