从若干个数中选出最大的任意两数取模之后的结果

严格次大值

对于此题

首先缩点

然后拓扑排序

维护到达每个点的最大值与严格次大值

感觉思路与代码都OK啊

then....

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <ctime> using namespace std; #define LL long long #define gc getchar()
inline int read() {int x = ; char c = gc; while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc; return x;}
inline LL read_LL() {LL x = ; char c = gc; while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc; return x;}
#undef gc const int N = 4e5 + , M = 2e6 + ;
int n, m, S, Q;
int A[N]; int Dfn[N], Low[N], Belong[N], Beljs, Tim;
bool vis[N];
int Stack[N], topp; pair <int, int> Pair[N];
struct Node {int u, v, nxt;} G[M];
int head1[N], cnt; inline void Link(int u, int v) {G[++ cnt].v = v; G[cnt].nxt = head1[u]; head1[u] = cnt;} void Tarjan(int u) {
Dfn[u] = Low[u] = ++ Tim;
vis[u] = ;
Stack[++ topp] = u;
for(int i = head1[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(!Dfn[v]) {
Tarjan(v);
Low[u] = min(Low[u], Low[v]);
} else if(vis[v]) Low[u] = min(Low[u], Low[v]);
}
if(Low[u] == Dfn[u]) {
int Max = , CMax = ;
Max = A[u];
vis[u] = ; Belong[u] = ++ Beljs;
Pair[Beljs].first = A[u]; Pair[Beljs].second = -;
while(Stack[topp] != u) {
int a = Stack[topp];
vis[a] = ;
Belong[a] = Beljs;
topp --;
if(A[a] > Max) {CMax = Max, Max = A[a];}
else if(A[a] != Max) CMax = max(CMax, A[a]);
Pair[Beljs] = make_pair(Max, CMax);
} topp --;
}
} Node E[M];
int head2[N], Du[N]; inline void ReLink(int u, int v) {Du[v] ++; E[++ cnt].v = v; E[cnt].nxt = head2[u]; head2[u] = cnt;} int use[N]; void Rebuild() {
for(int i = ; i <= Beljs; i ++) head2[i] = -;
cnt = ;
for(int u = ; u <= n; u ++)
for(int i = head1[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(Belong[u] != Belong[v] && use[Belong[v]] != u) {
use[Belong[v]] = u;
// cout << Belong[u] << " " << Belong[v] << "\n";
ReLink(Belong[u], Belong[v]);
}
}
} int Que[N]; bool beuse[N]; void Topsort() {
int h = , t = ;
// for(int i = 1; i <= Beljs; i ++) if(Du[i] == 0) Que[++ t] = i;
Que[++ t] = Belong[S];
while(h <= t) {
int topu = Que[h ++];
beuse[topu] = ;
for(int i = head2[topu]; ~ i; i = E[i].nxt) {
int v = E[i].v;
Du[v] --;
if(Du[v] == ) Que[++ t] = v;
int B[];
// cout << Pair[topu].first << " " << Pair[topu].second << " " << Pair[v].first << " " << Pair[v].second << "\n";
B[] = Pair[topu].first, B[] = Pair[topu].second, B[] = Pair[v].first, B[] = Pair[v].second;
sort(B + , B + );
Pair[v].first = B[];
int j = ;
while(B[j] == B[]) j --;
Pair[v].second = B[j];
}
}
} int main() {
// srand(time(0) - 99999);
// freopen("gg.in", "r", stdin);
// freopen("gg.out", "w", stdout);
n = read(), m = read(), Q = read(), S = read();
for(int i = ; i <= n; i ++) A[i] = read();
for(int i = ; i <= n; i ++) head1[i] = -;
for(int i = ; i <= m; i ++) {
int u = read(), v = read();
Link(u, v);
}
for(int i = ; i <= n; i ++)
if(!Dfn[i])
Tarjan(i);
// for(int i = 1; i <= Beljs; i ++) {
// cout << Pair[i].first << " " << Pair[i].second << "\n";
// }
// return 0;
Rebuild();
// for(int i = 1; i <= Beljs; i ++) {
// for(int j = head2[i]; ~ j; j = E[j].nxt) {
// int v = E[j].v;
// cout << i << " " << v << "\n";
// }
// }
Topsort();
for(int i = ; i <= Q; i ++) {
int a = read();
if(beuse[Belong[a]] == ) cout << - << " ";
else cout << Pair[Belong[a]].second << " ";
// if(ans == 0) cout << -1 << " ";
// cout << ans << " ";
}
return ;
}
/*
8 10 5 1
5 5 5 7 5 5 5 5
1 2
2 3
3 1
3 4
5 1
6 5
1 6
6 8
8 7
7 6
1 2 3 4 5
*/

*51nod 1815的更多相关文章

  1. 【51Nod 1815】【算法马拉松 23】调查任务

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1815 tarjan缩点后在DAG上递推即可. 每个点维护所有根到它的路径 ...

  2. 51Nod 1815 调查任务

    发现绍一的人很喜欢做51nod,不得不说这还是一个很全能的良心OJ 但是做的这道题就一点都不良心了,简直是毒瘤,调了一早上 首先我们考虑让一条路径的\(a_x\ mod\ a_y\)的值最大,我们简单 ...

  3. 51nod图论题解(4级,5级算法题)

    51nod图论题解(4级,5级算法题) 1805 小树 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 她发现她的树的点上都有一个标号(从1到n),这些树都在空 ...

  4. 【51Nod 1244】莫比乌斯函数之和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...

  5. 51Nod 1268 和为K的组合

    51Nod  1268  和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...

  6. 51Nod 1428 活动安排问题

    51Nod   1428  活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...

  7. 51Nod 1278 相离的圆

    51Nod 1278 相离的圆 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 1278 相离的圆 基 ...

  8. 【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1501 dp求出环状不连续的前缀和,剩下东西都可以算出来,比较繁琐. 时间 ...

  9. 【51Nod 1622】【算法马拉松 19C】集合对

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1622 简单题..直接暴力快速幂 #include<cstdio&g ...

随机推荐

  1. Spring AOP日志实现(一)

    前置通知:获取访问的类,访问的方法,带参数和不带参数的 日志表信息描述字段: 获取访问时长:

  2. 手动编译ts的经过

    动机 以前写ts或者es6,都是用在脚手架搭建的项目中,比如vue和react,当时当我识图写一个ts的demo的,我还要创建一个完整的vue或者react项目?明显不合适,那就要研究一下如何手动搭建 ...

  3. 模拟费用流 & 可撤销贪心

    1. CF730I Olympiad in Programming and Sports 大意: $n$个人, 第$i$个人编程能力$a_i$, 运动能力$b_i$, 要选出$p$个组成编程队, $s ...

  4. Error while launching application Error: spawn ENOMEM 解决

    当NodeJs PM2 无法启动应用 出现 Error while launching application Error: spawn ENOMEM 错误时     执行一下  pm2 update ...

  5. Android SDK版本号 与 API Level 对应关系 201911

    API是开发用的,所以API LEVEL可以认为是内部的:而SDK的版本提供了新特性给用户,是外部可见的. 可以查看以下网址以获取最新的对应关系:  http://developer.android. ...

  6. 自定义标签之inclusion_tag

    1.在当前app下创建templatetags文件夹 2.在templatetags文件夹下面创建自定义的mytag.py文件 3.在mytag.py文件中的代码 from django.templa ...

  7. Windows如何打开/关闭 服务

    先右键Windows主菜单,点击计算机管理: 点击服务和应用程序: 点击服务:

  8. Linux学习笔记之二

    vim编辑器 :三种工作模式 vim /tmp/xueying.txt 命令模式 a.i.o/esc     \  :wq  保存并退出 /              \ 输入模式           ...

  9. Zookeeper配置安装

    单机模式: 1:修改hosts文件 ​ 2:下载解压zookeeper.tar文件 3:创建data目录和logs目录 进入zookeeper目录下创建 ​ 4:复制一份zoo_sample.cfg配 ...

  10. Python笔记(30)-----logger

    转自: https://www.jb51.net/article/139080.htm logging模块介绍 Python的logging模块提供了通用的日志系统,熟练使用logging模块可以方便 ...