[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。

输入示例

9 31
10 20 30 40 50 60 70 80 90
3 1 2
1 1 3
1 1 2
1 8 9
1 2 4
1 2 5
1 4 6
1 4 7
3 1 8
3 8 8
1 8 9
3 8 8
3 7 5
3 7 3
1 4 1
3 7 5
3 7 3
1 5 7
3 6 5
3 3 6
1 2 4
1 5 5
3 3 6
2 8 180
3 8 8
2 9 190
3 9 9
2 5 150
3 3 6
2 1 210
3 3 6

输出示例

-1
-1
80
170
180
170
190
170
250
280
280
270
370
380
580

数据规模及约定

对于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;
}

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5369321.html

[BZOJ2959]长跑——新技能:LCT+缩圈相关推荐

  1. 专家都鼓励嵌入式工程师们走出舒适圈、学习新技能,才能与时俱进

    回忆起来,不知什么时候开始,整个it业界开始习惯用开源软件来开发应用程序(Apps),产业专家也鼓励嵌入式工程师们走出舒适圈.学习新技能,才能与时俱进.正是如此,越来越多的人加入学习嵌入式的大军,致使 ...

  2. 开课吧python小课学了有用吗-(内推实习)年薪30万,大量缺人,这个技能在金融圈到底有多吃香?...

    原标题:(内推实习)年薪30万,大量缺人,这个技能在金融圈到底有多吃香? 论近年来,金融圈最火爆的语言技能,非Python莫属. 四大:不想被淘汰,就得学Python 四大不仅借助Python实现底稿 ...

  3. #新技能# ps 简单抠图【持续更新】

    2019独角兽企业重金招聘Python工程师标准>>> 今天,姑姑叫我帮忙 ps,最近生意太好,她太忙了,其实本人并未学过 ps 啊,不过感觉不难,之前见高手弄过类似的,所以满心欢喜 ...

  4. OSChina 周二乱弹 ——女王节 教你撩妹新技能

    2019独角兽企业重金招聘Python工程师标准>>> 女王节 无论你的她,是女汉子,还是女神(经) 3.8这天,她都是女王 这天女王们地位无比高尚! 要伺候好你们的女王大人哦! 能 ...

  5. 还在一张张切图?PS快速切图新技能助你解放双手

    什么?你还在一张张处理??? 切图和标注一直是多数设计师最耗时且最不愿意做的事情,PS快速切图新技能,教你解放双手,快上车. 本文纲要 规则切图 不规则切图 快速批量切图 快速批量切出不同平台各种尺寸 ...

  6. 亲测有用!轻松get新技能的四步学习法

    全文共1965字,预计学习时长7分钟 图源:unsplash 置身于滚滚的庞大信息流当中,我们常常会不知所措.新框架和新技术接踵而至,每个人都在声称自己的比其他框架和技术更快.更安全.更高效.作为开发 ...

  7. Idea使用又Get新技能

    有些功能不是不会用,或许只是你不知道有这么一个东西的存在.昨天刷朋友圈看到超哥晒"红酒与代码"的照片,看了配图Get到新技能,也解决了日常遇到的问题,分享给大家. 就是上面这幅图. ...

  8. AI时代,产品经理需要掌握的5项新技能

    不同于传统的产品经理,AI时代的产品经理更加注重的如何将技术应用在业务问题上.AI时代,产品经理最重要的职责就是提供数据规范,所以这也要求产品经理对数据有足够的认识.文章对AI时代产品经理需要掌握的新 ...

  9. 学习新技能时,大脑在如何发生改变?

    来源:中国生物技术网 众所周知,无论是一项运动.一种乐器还是一门手艺,掌握一项新技能都是需要花费时间并进行训练的.虽然我们都知道健康的大脑能够应付的来,但是为了开发出新行为大脑如何发生改变科学家们对此 ...

  10. 企业网络推广之下的“盒马鲜生”新零售逐渐“破圈”而出

    还记得前两天的盒马鲜生与创4的热搜吗?因一同音"hema"的学员和马与盒马鲜生结下不解之缘,盒马鲜生为和马退出而打抱不平,随着粉丝与路人的关注让盒马鲜生在微博热搜上居高不下,甚至还 ...

最新文章

  1. mysql删除重复的判断_MySQL中查询、删除重复记录一共有多少种方法?
  2. Linux 内核定时器使用 二 高精度定时器 hrtimer 的用例
  3. C++ primer 第8章 IO库
  4. 局部内部类 java 1614958356
  5. [BZOJ3238][AHOI2013]差异 [后缀数组+单调栈]
  6. 【Flink】Flink 1.9 升级 1.12.4 本地可以运行 打包后 集群运行就找不到类 ClassNotFoundException
  7. 校企合作与集成电路--华为在行动
  8. java如何实现进程间的通信?
  9. 文章发送到多平台软件:融媒宝
  10. QQ拼音输入法词库和搜狗输入法词库[相互导入](使用Excel公式)
  11. mysql主从配置启动失败_Mysql主从配置错误及解决办法
  12. Prism4学习笔记(六):UI Composition
  13. 推荐10个易上手好用的H5网页编辑工具
  14. 微信公众号申请注意事项
  15. java项目-第150期ssm网络视频播放器-java毕业设计_计算机毕业设计
  16. Python学习周记(序列)
  17. 设计原则—SOLID(SRP)
  18. 风暴魔域怎么在电脑上玩 风暴魔域电脑版玩法教程
  19. java使用dbcp2数据库连接池
  20. 【自然语言处理与文本分析】文本特征提取方法总结。关键词提取方法。公认效果较好的IDF,RCF。

热门文章

  1. KIS专业版-即时库存查询自定义开发
  2. Biopython -- Bio.Entrez module
  3. android图片轮播序号,求一组详细的图片轮播HTML代码(图片下面标有图片序号,鼠标点击相应序号,播放所对应图片;鼠标点击图片时链接到相应页面) 和一些电子商务网站首页的广告差不多...
  4. 向工程腐化开炮 | manifest 治理
  5. 打开我的电脑的快捷键
  6. Linux部署rsyslog日志服务器(主机部分)
  7. 智能家居APP的竞品分析报告(米家)
  8. iqc工作职责和工作内容_iqc工作职责流程
  9. HTML 修真录------深渊三君王
  10. iPhone模拟器截图