[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+缩圈的更多相关文章

  1. 5332盛照宗 如何获取新技能+c语言学习调查

    如何获取新技能+c语言学习调查 你有什么技能比大多人(超过90%以上)更好? 如果问我有没有什么技能比大多数人,并且是90%的人好,我还真不敢说有,因为世界上有70亿人,要比63亿人做的好才行啊.我也 ...

  2. 腾讯优测干货精选| 安卓开发新技能Get -常用必备小工具汇总

    文/腾讯公司 陈江峰 优测小优有话说: 移动研发及测试干货哪里找?腾讯优测-优社区你值得拥有~ 开发同学们都知道,安卓开发路上会碰到很多艰难险阻,一不小心就被KO.这时候,没有新技能傍身怎么行?今天我 ...

  3. 20155332 如何获取新技能+c语言学习调查

    如何获取新技能+c语言学习调查 你有什么技能比大多人(超过90%以上)更好? 如果问我有没有什么技能比大多数人,并且是90%的人好,我还真不敢说有,因为世界上有70亿人,要比63亿人做的好才行啊.我也 ...

  4. hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)

    hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...

  5. [站点推荐]001.学习新技能的37个最佳网站(The 37 Best Websites To Learn Something New)

    忘了过于褒奖的学校.整天呆在拥挤的教室而效果却差得可怜.这些网站和应用涵盖了科学.艺术和技术的无数话题.它们可以教会你实践练习任何技能,从制作豆 沙到用 node.js 开发 app,而且它们都是免费 ...

  6. Git新技能-stash操作

    最近开发的工期非常紧迫,一直在忙各种杂七杂八的事情,负责人都还没有创建好测试环境, 所以代码也不能部署.可是项目经理催促开发进度又催得很急,新的开发需求必须在指定的时间内 完成,我们只得想办法去克服困 ...

  7. BZOJ2959长跑——LCT+并查集(LCT动态维护边双连通分量)

    题目描述 某校开展了同学们喜闻乐见的阳光长跑活动.为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上熙熙攘攘,摩肩接踵,盛况空前. 为 ...

  8. bzoj2959: 长跑(LCT+并查集)

    题解 动态树Link-cut tree(LCT)总结 LCT常数大得真实 没有环,就是\(lct\)裸题吧 有环,我们就可以绕环转一圈,缩点 怎么搞? 当形成环时,把所有点的值全部加到一个点上,用并查 ...

  9. bzoj2959: 长跑 LCT+并查集+边双联通

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2959 题解 调了半天,终于调完了. 显然题目要求是求出目前从 \(A\) 到 \(B\) 的可 ...

随机推荐

  1. Android--自动搜索提示

    一. 效果图 在Google或者百度搜索的时候,在输入关键词都会出现自动搜索的提示内容,类似如下的效果,输入b 则出现包含b的相关词条 二. 布局代码 <?xml version="1 ...

  2. OpenGLES 2.0 可编程渲染管线

    OpenGL ES 2.0 与 OpenGL ES 1.x 渲染管线的最大区别就是: 顶点着色器.片元着色器是可编程的,替代了原来的固定管线的很多功能.

  3. Use Windows Azure AD to create SSO projects

    Keywords Windows Azure AD, SSO Summary Use Windows Azure AD to create SSO projects Detailed Scenario ...

  4. [USACO 3.1.4]rect1(漂浮法/矩形切割)

    描述 N个不同的颜色的不透明的长方形(1 <= N <= 1000)被放置在一张横宽为A竖长为B的白纸上. 这些长方形被放置时,保证了它们的边与白纸的边缘平行. 所有的长方形都放置在白纸内 ...

  5. Bootstrap3.0学习第十三轮(导航条)

    详情请查看http://aehyok.com/Blog/Detail/20.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链接:ht ...

  6. Javascript基础系列之(三)数据类型 (布尔型 Boolean)

    javascript同样有布尔型,可选值,true or fasle. var marr = true ; document.write(typeof(marr) + "<br> ...

  7. 【web必知必会】—— 使用DOM完成属性填充

    本文介绍了使用DOM的简单方法实现动态加载图片的功能. 前文介绍了: 1 DOM四个常用的方法 首先看一下效果,初始时是一个相册,可以点击导航,切换图片,并切换下方显示内容: 点击house,可以动态 ...

  8. HYSBZ1036 树链剖分

    这题我建了2棵线段树,这样来处理 最值和和值,简单的题目. #include<queue> #include<stack> #include<cmath> #inc ...

  9. SourceTree&Git部分名词解释

    SourceTree&Git部分名词解释 克隆(clone):从远程仓库URL加载创建一个与远程仓库一样的本地仓库 提交(commit):将暂存文件上传到本地仓库(我们在Finder中对本地仓 ...

  10. Spring MVC实现防止表单重复提交(转)

    Spring MVC拦截器+注解方式实现防止表单重复提交