2.16学习总结

1.邮递员送信(dijkstra 不只是从起到到目标点,还要走回去)
2.炸铁路(并查集)
3.统计方形(数据加强版)(排列组合)
4.滑雪(记忆化)
5.小车问题(数学问题)
6.ACM(记忆化,搜索)
7.奶牛的耳语(二分)
8.计算器的改良(模拟)
9.L-shapes(遍历)
10.Alternating Heights(拓扑排序+二分)

邮递员送信https://www.luogu.com.cn/problem/P1629

题目描述

有一个邮递员要送东西,邮局在节点 11。他总共要送 �−1n−1 样东西,其目的地分别是节点 22 到节点 �n。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有 �m 条道路。这个邮递员每次只能带一样东西,并且运送每件物品过后必须返回邮局。求送完这 �−1n−1 样东西并且最终回到邮局最少需要的时间。

输入格式

第一行包括两个整数,�n 和 �m,表示城市的节点数量和道路数量。

第二行到第 (�+1)(m+1) 行,每行三个整数,�,�,�u,v,w,表示从 �u 到 �v 有一条通过时间为 �w 的道路。

输出格式

输出仅一行,包含一个整数,为最少需要的时间。

输入输出样例

输入 #1复制

5 10
2 3 5
1 5 5
3 5 6
1 2 8
1 3 8
5 3 4
4 1 8
4 5 3
3 5 6
5 4 2

输出 #1复制

83

说明/提示

对于 30%30% 的数据,1≤�≤2001≤n≤200。

对于 100%100% 的数据,1≤�≤1031≤n≤103,1≤�≤1051≤m≤105,1≤�,�≤�1≤u,v≤n,1≤�≤1041≤w≤104,输入保证任意两点都能互相到达。

思路:与平常最短路不同的是,这个需要走回去,那就把邻接表反过来,在走一遍dijkstra

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N=1005;
int n,m;struct node{int to;int w;node(int b,int c){to=b;w=c;}
};
vector<node>e1[N];
vector<node>e2[N];
int dis1[N],dis2[N];
struct s_node{int id;int n_dis;s_node(int a,int b){id=a;n_dis=b;}bool operator < (const s_node &a )const{return n_dis>a.n_dis;}
};void dijkstra1(){priority_queue<s_node>q;bool done[N];for (int i=1;i<=n;++i){done[i]=false;dis1[i]=INF;}dis1[1]=0;q.push(s_node(1,dis1[1]));while (!q.empty()){s_node u=q.top(); q.pop();if (done[u.id]) continue;done[u.id]=true;for (int i=0;i<e1[u.id].size();++i){node y=e1[u.id][i];if (done[y.to]) continue;if (dis1[y.to]> u.n_dis+y.w){dis1[y.to]=u.n_dis+y.w;q.push(s_node(y.to,dis1[y.to])); }}}
}void dijkstra2(){priority_queue<s_node>q2;bool done[N];for (int i=1;i<=n;++i){done[i]=false;dis2[i]=INF;}dis2[1]=0;q2.push(s_node(1,dis2[1]));while (!q2.empty()){s_node u=q2.top(); q2.pop();if (done[u.id]) continue;done[u.id]=true;for (int i=0;i<e2[u.id].size();++i){node y=e2[u.id][i];if (done[y.to]) continue;if (dis2[y.to]> u.n_dis+y.w){dis2[y.to]=u.n_dis+y.w;q2.push(s_node(y.to,dis2[y.to])); }}}
}signed main(){cin>>n>>m;for (int i=0;i<m;++i){int a,b,c;cin>>a>>b>>c;e1[a].push_back(node(b,c));e2[b].push_back(node(a,c));}dijkstra1();int res=0;for (int i=1;i<=n;++i){res+=dis1[i];}dijkstra2();for (int i=1;i<=n;++i){res+=dis2[i];}cout<<res;
}
炸铁路https://www.luogu.com.cn/problem/P1656

题目描述

A 国派出将军 uim,对 B 国进行战略性措施,以解救涂炭的生灵。

B 国有 �n 个城市,这些城市以铁路相连。任意两个城市都可以通过铁路直接或者间接到达。

uim 发现有些铁路被毁坏之后,某两个城市无法互相通过铁路到达。这样的铁路就被称为 key road。

uim 为了尽快使该国的物流系统瘫痪,希望炸毁铁路,以达到存在某两个城市无法互相通过铁路到达的效果。

然而,只有一发炮弹(A 国国会不给钱了)。所以,他能轰炸哪一条铁路呢?

输入格式

第一行 �,� (1≤�≤150n,m (1≤n≤150,1≤�≤5000)1≤m≤5000),分别表示有 �n 个城市,总共 �m 条铁路。

以下 �m 行,每行两个整数 �,�a,b,表示城市 �a 和城市 �b 之间有铁路直接连接。

输出格式

输出有若干行。

每行包含两个数字 �,�a,b,其中 �<�a<b,表示 〈�,�〉〈a,b〉 是 key road。

请注意:输出时,所有的数对 〈�,�〉〈a,b〉 必须按照 �a 从小到大排序输出;如果�a 相同,则根据 �b 从小到大排序。

输入输出样例

输入 #1复制

6 6
1 2
2 3
2 4
3 5
4 5
5 6

输出 #1复制

1 2
5 6

思路:用并查集,先每次循环去掉一个遍,然后验证一边是否成立

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N=200;
int n,m;struct node{int from;int to;
}a[5005];bool cmp(const node& a, const node& b){if (a.from==b.from) return a.to<b.to;else return a.from<b.from;
}int f[N],cnt=0;int find(int x){if (f[x]==x){return x;}else if (f[x]!=x){f[x]=find(f[x]);return f[x];}
}node b[5005];void unionn(int i,int j){f[find(i)]=find(j);
}void check(){for (int i=1;i<=m;++i){for (int i=1;i<=n;++i) f[i]=i;for (int j=1;j<=m;++j){if (i==j)continue;unionn(a[j].from,a[j].to);}for (int k=1;k<n;++k){if (find(k)!=find(k+1)){cnt++;b[cnt].from=a[i].from;b[cnt].to=a[i].to;break;}}}for (int i=1;i<=cnt;++i){if (b[i].from>b[i].to){int tmp=b[i].from;b[i].from=b[i].to;b[i].to=tmp;}}sort(b+1,b+1+cnt,cmp);for (int i=1;i<=cnt;++i){cout<<b[i].from<<" "<<b[i].to<<endl;}
}signed main(){cin>>n>>m;for (int i=1;i<=m;++i){cin>>a[i].from>>a[i].to;}sort(a+1,a+1+m,cmp);check();
}
统计方形(数据加强版)https://www.luogu.com.cn/problem/P2241

题目背景

1997年普及组第一题

题目描述

有一个 �×�n×m 方格的棋盘,求其方格包含多少正方形、长方形(不包含正方形)。

输入格式

一行,两个正整数 �,�n,m(�≤5000,�≤5000n≤5000,m≤5000)。

输出格式

一行,两个正整数,分别表示方格包含多少正方形、长方形(不包含正方形)。

输入输出样例

输入 #1复制

2 3

输出 #1复制

8 10

思路:用数学的想法,在n×m的棋盘中,一个可以有C_{n+1}^{2}\textrm{}×C_{m+1}^{2}\textrm{}个矩形,然后正方形的最大边长是到min{m,n},所以正方形的个数是\sum_{1}^{n}(n+1-i)(m+1-i)(这里假定n<m),所以矩形的数量减去正方形就是长方形的数量

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fint n,m;signed main(){cin>>n>>m;int cnt=0;int x=((n+1)*n/2)*((m+1)*m/2);for (int i=1;i<=min(m,n);++i){cnt+=(n-i+1)*(m-i+1);}cout<<cnt<<" "<<x-cnt;
}
滑雪https://www.luogu.com.cn/problem/P1434

题目描述

Michael 喜欢滑雪。这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael 想知道在一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子:

1   2   3   4   5
16  17  18  19  6
15  24  25  20  7
14  23  22  21  8
13  12  11  10  9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度会减小。在上面的例子中,一条可行的滑坡为 24−17−16−124−17−16−1(从 2424 开始,在 11 结束)。当然 2525-2424-2323-……-33-22-11 更长。事实上,这是最长的一条。

输入格式

输入的第一行为表示区域的二维数组的行数 �R 和列数 �C。下面是 �R 行,每行有 �C 个数,代表高度(两个数字之间用 11 个空格间隔)。

输出格式

输出区域中最长滑坡的长度。

输入输出样例

输入 #1复制

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

输出 #1复制

25

说明/提示

对于 100%100% 的数据,1≤�,�≤1001≤R,C≤100。

思路:记忆化+dfs,每个点来一遍dfs,就可以找到最大长度了,记忆化可以减少时间消耗

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N =105;
int a[N][N],s[N][N];
int m,n;int dir[4][2]={{0,1},{1,0},{-1,0},{0,-1}};void dfs(int x,int y){if (s[x][y]) return;s[x][y]=1;for (int i=0;i<4;++i){int xx=x+dir[i][0],yy=y+dir[i][1];if (xx < 1 || xx >m || yy<1 || yy >n) continue;if (a[x][y]>a[xx][yy]){dfs(xx,yy);s[x][y]=max(s[x][y],s[xx][yy]+1);}}
}signed main(){cin>>m>>n;for (int i=1;i<=m;++i){for (int j=1;j<=n;++j){cin>>a[i][j];}}int ans=0;for (int i=1;i<=m;++i){for (int j=1;j<=n;++j){dfs(i,j);ans=max(ans,s[i][j]);}}cout<<ans;
}
小车问题https://www.luogu.com.cn/problem/P1258

题目描述

甲、乙两人同时从 A 地出发要尽快同时赶到 B 地。出发时 A 地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达。

输入格式

仅一行,三个实数,分别表示 AB 两地的距离 �s,人的步行速度 �a,车的速度 �b。

输出格式

两人同时到达 B 地需要的最短时间,保留 66 位小数。

输入输出样例

输入 #1复制

120 5 25

输出 #1复制

9.600000

说明/提示

数据规模与约定

对于 100%100% 的数据,保证 0≤�,�,�≤1090≤s,a,b≤109。

思路:解方程

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fdouble s,a,b;signed main(){cin>>s>>a>>b;double t=((a+3*b)/(b*(3*a+b)))*s;printf("%.6lf",t);
}
ACMhttps://www.luogu.com.cn/problem/P7793

题目背景

Zagreb 大学的团队的成员 Stjepan、Ivan 和 Gustav 正在摩洛哥参加 ACM 国际大学生程序设计竞赛的世界决赛。他们的技术指导 Goran 想出了一个无敌的策略,用于解决决赛中的题目。

题目描述

在一开始,每个团队成员迅速估计 �n 道题目中每题的难度。这些难度用 11 到 55 的数字描述,数字越大,难度也就越大。

在这之后,他们之间将分配任务。为了简单起见,任务阵列将被分成三部分,以便每个团队成员得到一个非空的连续任务序列来思考。这种分配是为了使估计的难度之和最小,而只计算被分配到该任务的团队成员的估计难度值。你的任务是计算这个最小的可能总和。

输入格式

输入共四行。

第一行输入一个整数 �n,表示问题的数量。
第二到第四行,第 �+1i+1 行 �n 个整数 ��,1,��,2,…,��,�di,1​,di,2​,…,di,n​,表示第 �i 号成员对于这 �n 道题目估计的难度。

输出格式

输出仅一行,一个整数,表示最小可能的估计难度总和。

输入输出样例

输入 #1复制

3
1 3 3
1 1 1
1 2 3

输出 #1复制

4

输入 #2复制

7
3 3 4 1 3 4 4
4 2 5 1 5 5 4
5 5 1 3 4 4 4

输出 #2复制

19

说明/提示

【样例 1 解释】

给第 11 号成员分配第 11 题,给第 22 号成员分配第 33 道题,给第 33 号成员分配第 22 道题。这样分配的难度总和为 1+1+2=41+1+2=4。可以证明没有难度总和更小的分配方案。

【数据范围】

对于所有数据,3⩽�⩽1.5×1053⩽n⩽1.5×105,1⩽��,�⩽51⩽di,j​⩽5。

思路:动态规划,遍历所有的情况,因为一共的三个人,所以C_{3}^{1}\textrm{}C_{2}^{1}\textrm{}一共6种情况(需要在意顺序)确定状态转移方程:可以从上一个编号的人或自己做上一题进行转移

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N=2e5+5;int n,dp[4][N],f[4][N],minn=INF;void dfs(int a,int b,int c){memset(dp,0x3f,sizeof(dp));dp[a][1]=f[a][1];for (int i=2;i<=n;++i){dp[a][i]=dp[a][i-1]+f[a][i];dp[b][i]=min(dp[a][i-1],dp[b][i-1])+f[b][i];dp[c][i]=min(dp[b][i-1],dp[c][i-1])+f[c][i];}minn=min(minn,dp[c][n]);
}signed main(){cin>>n;for (int i=1;i<=3;++i){for (int j=1;j<=n;++j){cin>>f[i][j];}}dfs(1,2,3);dfs(1,3,2);dfs(2,1,3);dfs(2,3,1);dfs(3,2,1);dfs(3,1,2);cout<<minn;
}
奶牛的耳语https://www.luogu.com.cn/problem/P1296

题目描述

在你的养牛场,所有的奶牛都养在一排呈直线的牛栏中。一共有 �n 头奶牛,其中第 �i 头牛在直线上所处的位置可以用一个整数坐标 ��(0≤��≤108)pi​(0≤pi​≤108) 来表示。在无聊的日子里,奶牛们常常在自己的牛栏里与其它奶牛交流一些八卦新闻。每头奶牛发出的声音响度是一样的,而由于声波的能量衰减,某头奶牛发出的声音只能被与它距离不超过 �(0≤�≤104)d(0≤d≤104) 的奶牛所听到,这样这对奶牛就称为可以相互交流的。现在给出所有奶牛的位置和声音所能传播的最远距离 �d ,请你编个程序来计算你的养牛场里究竟有多少对可以相互交流的奶牛。

输入格式

第一行包含两个整数 �,�n,d。

第二行包含 �n 个整数,每个整数都是一个坐标 ��pi​,描述一头奶牛在直线上的位置。

输出格式

一个数,表示养牛场中可以相互交流奶牛的对数。

输入输出样例

输入 #1复制

5 10
10 12 16 37 40

输出 #1复制

4

说明/提示

数据规模

对于 40%40% 的数据,1≤�≤1031≤n≤103。

对于 100%100% 的数据,1≤�≤1061≤n≤106。

思路:运用二分的思想,先对数组排序,然后用二分找到第一个听不见的位置,然后,加到计数器里面

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N=1e6+5;int n,d,a[N];signed main(){cin>>n>>d;for (int i=1;i<=n;++i) cin>>a[i];sort(a+1,a+1+n);int ans=0;for (int i=1;i<=n;++i){int p=upper_bound(a+i+1,a+1+n,a[i]+d)-a;ans+=p-i-1;}cout<<ans;
}
计算器的改良https://www.luogu.com.cn/problem/P1022

题目背景

NCL 是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手 ZL 先生。

题目描述

为了很好的完成这个任务,ZL 先生首先研究了一些一元一次方程的实例:

  • 4+3�=84+3x=8。

  • 6�−5+1=2−2�6a−5+1=2−2a。

  • −5+12�=0−5+12y=0。

ZL 先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及 +-= 这三个数学符号(当然,符号“-”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。

你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。

输入格式

一个一元一次方程。

输出格式

解方程的结果(精确至小数点后三位)。

输入输出样例

输入 #1复制

6a-5+1=2-2a

输出 #1复制

a=0.750

思路:模拟

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N=100;int l;
double x,flag,mid,a[N];
char c,p;signed main(){l=1,flag=1;while (c!='='){c=getchar();if (c=='+'){flag=1;l++;}else if (c=='-'){flag=-1;l++;}if (c>='0' && c<='9'){if (a[l]==0){a[l]+=(c-'0')*flag;}else{a[l]=a[l]*10+(c-'0')*flag;}}if (c>='a' && c<='z'){p=c;if (a[l]==0) x+=flag;else x+=a[l];a[l]=0;l--;}}mid=l,l++,flag=1;while (c!='\n'){c=getchar();if (c=='+'){flag=1;l++;}else if (c=='-'){flag=-1;l++;}if (c>='0' && c<='9'){if (a[l]==0){a[l]+=(c-'0')*flag;}else{a[l]=a[l]*10+(c-'0')*flag;}}if (c>='a' && c<='z'){p=c;if (a[l]==0) x-=flag;else x-=a[l];a[l]=0;l--;}}int sum=0;for (int i=1;i<=l;++i){if (i<=mid){sum-=a[i];}else {sum+=a[i];}}if (!(sum/x)){printf("%c=0.000",p);}else {printf("%c=%.3lf",p,sum/x);}
}
L-shapeshttps://www.luogu.com.cn/problem/CF1722F

题目描述

An L-shape is a figure on gridded paper that looks like the first four pictures below. An L-shape contains exactly three shaded cells (denoted by *), which can be rotated in any way.

You are given a rectangular grid. Determine if it contains L-shapes only, where L-shapes can't touch an edge or corner. More formally:

  • Each shaded cell in the grid is part of exactly one L-shape, and
  • no two L-shapes are adjacent by edge or corner.

For example, the last two grids in the picture above do not satisfy the condition because the two L-shapes touch by corner and edge, respectively.

输入格式

The input consists of multiple test cases. The first line contains an integer �t ( 1≤�≤1001≤t≤100 ) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers �n and �m ( 1≤�,�≤501≤n,m≤50 ) — the number of rows and columns in the grid, respectively.

Then �n lines follow, each containing �m characters. Each of these characters is either '.' or '*' — an empty cell or a shaded cell, respectively.

输出格式

For each test case, output "YES" if the grid is made up of L-shape that don't share edges or corners, and "NO" otherwise.

You can output the answer in any case (for example, the strings "yEs", "yes", "Yes" and "YES" will be recognized as a positive answer).

题意翻译

L形在网格纸上形如下面的前四张图片。L形正好包含三个阴影单元(用*表示),可以以任何方式旋转。

现给你一个矩形网格。确定它是否仅包含L形,其中L形不能接触边或角,也就是说网格中的每个阴影单元正好是一个L形的一部分,并且没有两个L形通过边或角相邻。

例如,上图中的最后两个网格不满足条件,因为两个L形分别通过角和边缘接触。

如果网格满足条件,则输出“YES”,否则输出“NO”。

输入输出样例

输入 #1复制

10
6 10
........**
.**......*
..*..*....
.....**...
...*.....*
..**....**
6 10
....*...**
.**......*
..*..*....
.....**...
...*.....*
..**....**
3 3
...
***
...
4 4
.*..
**..
..**
..*.
5 4
.*..
**..
....
..**
..*.
3 2
.*
**
*.
2 3
*..
.**
3 2
..
**
*.
3 3
.**
*.*
**.
3 3
..*
.**
..*

输出 #1复制

YES
NO
NO
NO
YES
NO
NO
YES
NO
NO

思路:把*都成1,其他都是0,找到特殊的四种情况,然后判断,把可以成立的变成0,最后遍历一边数组,如果还有1那就不行

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N=55;int t,n,m,a[N][N];void check(int i,int j){if (a[i+1][j] && a[i+1][j+1] && !a[i-1][j-1] && !a[i-1][j] && !a[i-1][j+1] && !a[i][j-1]  && !a[i][j+1] && !a[i][j+2]&& !a[i+1][j-1] && !a[i+1][j+2] && !a[i+2][j-1] && !a[i+2][j]  && !a[i+2][j+1] && !a[i+2][j+2]){a[i][j]=a[i+1][j] = a[i+1][j+1] = 0;return;}if (a[i][j+1] && a[i+1][j+1] && !a[i-1][j-1] && !a[i-1][j] && !a[i-1][j+1] && !a[i-1][j+2] && !a[i][j-1]  && !a[i][j+2]&& !a[i+1][j-1] && !a[i+1][j] && !a[i+1][j+2] && !a[i+2][j]  && !a[i+2][j+1] && !a[i+2][j+2]){a[i][j+1]=a[i+1][j+1] = a[i][j] = 0;return;}if (a[i+1][j] && a[i+1][j-1] && !a[i-1][j-1] && !a[i-1][j] && !a[i-1][j+1] && !a[i][j-2] && !a[i][j-1]  && !a[i][j+1]&& !a[i+1][j-2] && !a[i+1][j+1] && !a[i+2][j-1] && !a[i+2][j]  && !a[i+2][j+1] && !a[i+2][j-2]){a[i+1][j]=a[i+1][j-1] = a[i][j] = 0;return;}if (a[i][j+1] && a[i+1][j] && !a[i-1][j-1] && !a[i-1][j] && !a[i-1][j+1] && !a[i-1][j+2] && !a[i][j-1]  && !a[i][j+2]&& !a[i+1][j-1] && !a[i+1][j+1] && !a[i+1][j+2]&& !a[i+2][j-1] && !a[i+2][j]  && !a[i+2][j+1] ){a[i][j]=a[i+1][j] = a[i][j+1] = 0;return;}
}signed main(){cin>>t;while (t--){cin>>n>>m;memset(a,0,sizeof(a));for (int i=1;i<=n;++i){for (int j=1;j<=m;++j){char c;	cin>>c;if (c=='*') a[i][j]=1;}}for (int i =1 ;i<=n ;++i ){for (int j =1 ; j<=m ;++ j){if (a[i][j] == 1) check(i,j);}}bool flag=true;for (int i =1 ;i<=n ;++i ){for (int j =1 ; j<=m ;++ j){if (a[i][j] == 1){flag=false;break;}}if (!flag) break;}if (!flag) cout<<"NO"<<endl;else cout<<"YES"<<endl;}
}
Alternating Heightshttps://www.luogu.com.cn/problem/P10050

题目描述

Troy 计划给 CCO 的学生拍一张合影,他向你寻求帮助。

有 �K 个学生,编号从 11 到 �K。Troy 忘记了学生的身高,但他记得没有两个学生的身高相同。

Troy 有一个序列 �1,�2,…,��A1​,A2​,…,AN​,表示合影中从左到右的学生顺序。一个学生可能在 �A 中出现多次。你不确定这张合影会怎么拍,但你不愿意认为 Troy 犯了错误。

Troy 会给你 �Q 个形式为 �,�x,y 的询问,每个询问为「给定学生序列 ��,��+1,…,��Ax​,Ax+1​,…,Ay​,他们的身高能否形成一个交替序列?」更具体地说,我们用 ℎ�hi​ 表示第 �i 个学生的身高。如果存在一种身高分配ℎ1,ℎ2,…,ℎ�h1​,h2​,…,hK​,使得 ℎ��>ℎ��+1<ℎ��+2>ℎ��+3<…ℎ��hAx​​>hAx+1​​<hAx+2​​>hAx+3​​<…hAy​​,回答 YES;否则回答 NO

注意,每个查询都是独立的:也就是说,询问 �i 的身高分配与询问 �j 的身高分配无关 (�≠�)(i=j)。

输入格式

第一行包含三个用空格分隔的整数 �,�N,K 和 �Q。

第二行包含 �N 个整数,表示 �1,�2,…,��(1≤��≤�)A1​,A2​,…,AN​(1≤Ai​≤K)。

接下来的 �Q 行,每行包含两个用空格分隔的整数 �x 和 �(1≤�<�≤�)y(1≤x<y≤N),表示一组查询。

输出格式

输出 �Q 行。第 �i 行,输出 YES 或者 NO,表示 Troy 的第 �i 个查询的答案。

输入输出样例

输入 #1复制

6 3 3
1 1 2 3 1 2
1 2
2 5
2 6

输出 #1复制

NO
YES
NO

说明/提示

样例说明

对于第一个询问,不可能有 ℎ1>ℎ1h1​>h1​,所以答案是 NO

对于第二个询问,ℎ1>ℎ2<ℎ3>ℎ1h1​>h2​<h3​>h1​ 的一种方案是 ℎ1=160 cm,ℎ2=140 cm,ℎ3=180 cmh1​=160 cm,h2​=140 cm,h3​=180 cm。另一种方案是 ℎ1=1.55 m,ℎ2=1.473 m,ℎ3=1.81 mh1​=1.55 m,h2​=1.473 m,h3​=1.81 m。

对于第三个询问,不可能同时有 ℎ1>ℎ2h1​>h2​ 和 ℎ1<ℎ2h1​<h2​。

数据范围

对于所有的数据,有 2≤�≤30002≤N≤3000,2≤�≤�2≤K≤N,1≤�≤1061≤Q≤106。

子任务编号

分值

�N

�K

�Q

11

1616

2≤�≤30002≤N≤3000

�=2K=2

1≤�≤1061≤Q≤106

22

2424

2≤�≤5002≤N≤500

2≤�≤min⁡(�,5)2≤K≤min(N,5)

1≤�≤1061≤Q≤106

33

2828

2≤�≤30002≤N≤3000

2≤�≤�2≤K≤N

1≤�≤20001≤Q≤2000

44

3232

2≤�≤30002≤N≤3000

2≤�≤�2≤K≤N

1≤�≤1061≤Q≤106

思路:看成图,如果存在环,那就无法成立,用拓扑排序判断是否成环,暴力搜会超时,用二分的思想,固定左端点,然后找到以此为左端点的最大区间长度

#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x& - (x))
#define int long long
#define INF 0x3f3f3f3f3f3f3f3fconst int N=3005;int n,k,Q,a[N],in[N],num[N],g[N][N],max_len[N];
queue<int>q;bool check(int l,int r){	//拓扑排序 int sum=0;memset(in,0,sizeof(in));	//记录入度 memset(num,0,sizeof(num));	//记录相邻的节点数 while (!q.empty()) q.pop();for (int i=l+1;i<=r;i+=2){		//指向高的 if (i-1>0){g[a[i]][++num[a[i]]]=a[i-1];in[a[i-1]]++;}if (i+1<=r){g[a[i]][++num[a[i]]]=a[i+1];in[a[i+1]]++;}}for (int i=1;i<=k;++i){	//入度为0就入队 if (!in[i]) q.push(i);}while (!q.empty()){int p=q.front(); q.pop();sum++;for (int i=1;i<=num[p];++i){in[g[p][i]]--;	//出队后,相邻点的入度减1 if (!in[g[p][i]]) q.push(g[p][i]);}}return sum==k;
}int erfen(int m){int l=m,r=n,maxn=0;while (l<=r){int mid=l+r>>1;if (check(m,mid)){	//以m为左端点的最长区间 maxn=max(maxn,mid);l=mid+1;}else r=mid-1;}return maxn;
}signed main(){cin>>n>>k>>Q;for (int i=1;i<=n;++i) cin>>a[i];for (int i=1;i<=n;++i) max_len[i]=erfen(i);for (int i=1;i<=Q;++i){int x,y;cin>>x>>y;if (max_len[x]<y) cout<<"NO"<<endl;else cout<<"YES"<<endl;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/686696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无人机系统组装与调试,多旋翼无人机组装与调试技术详解,无人机飞控系统原理

多旋翼无人机飞控系统的组装 在开始组装前&#xff0c;确保您已准备好所有必要的工具和材料。这包括螺丝刀、电烙铁、焊台、杜邦线、飞控板、GPS模块、电机、桨叶等。 飞控安装 安全开关安装&#xff0c;将安全开关固定在机架上。将安全开关的线插到飞控SWITCH插口上。 电调…

【半监督图像分割 2023 】BHPC

【半监督图像分割 2023 】BHPC 论文题目&#xff1a;Semi-supervised medical image segmentation via hard positives oriented contrastive learning 中文题目&#xff1a;通过面向硬阳性的对比学习进行半监督医学图像分割 论文链接&#xff1a; 论文代码&#xff1a;https:/…

亚马逊、国际站、速卖通新店怎么销量破冰?自养号测评爆款打造思路

亚马逊作为全球最大的电子商务平台之一&#xff0c;吸引了众多卖家进驻其平台。对于新店铺来说&#xff0c;如何在竞争激烈的市场中突破销量瓶颈&#xff0c;成为卖家们关注的焦点。 一、亚马逊新店怎么销量破冰&#xff1f; 优化商品信息&#xff1a;在亚马逊平台上&#xff…

牛客网SQL进阶128:未完成试卷数大于1的有效用户

官网链接&#xff1a; 未完成试卷数大于1的有效用户_牛客题霸_牛客网现有试卷作答记录表exam_record&#xff08;uid用户ID, exam_id试卷ID, st。题目来自【牛客题霸】https://www.nowcoder.com/practice/46cb7a33f7204f3ba7f6536d2fc04286?tpId240&tqId2183007&ru%2…

【深度学习】Pytorch 系列教程(三):PyTorch数据结构:2、张量的数学运算(1):向量运算(加减乘除、数乘、内积、外积、范数、广播机制)

文章目录 一、前言二、实验环境三、PyTorch数据结构0、分类1、Tensor&#xff08;张量&#xff09;1. 维度&#xff08;Dimensions&#xff09;2. 数据类型&#xff08;Data Types&#xff09;3. GPU加速&#xff08;GPU Acceleration&#xff09; 2、张量的数学运算1. 向量运算…

蓝桥杯真题:扑克牌移动

import java.util.*; public class Main {public static List moveCard(List src){if(srcnull) return null;List dst new Vector();for(;;){if(src.size()0) break; // 填空src.add(src.remove(0));//remove(0) 是一个 List 接口中的方法调用&#xff0c;它表示移除列表中指…

Sentinel注解@SentinelResource详解

Sentinel注解SentinelResource详解 熔断 针对访问超过限制【sentinel中配置的限制】的资源&#xff0c;通过java代码配置&#xff0c;返回一个自定义的结果&#xff0c;需要用到 SentinelResource 注解的 blockHandlerClass 和 blockHandler 属性。 blockHandlerClass&#…

数据集合

目录 并集 union union all 区别 交集 intersect 差集 minus 错误操作 Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 常用的数学集合有&#xff1a;交集、并集、差集、补集 每一次查询实际上都会返回数据集合&#xff0c;…

【机器学习】机器学习常见算法详解第4篇:KNN算法计算过程(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论机器学习算法相关知识。机器学习算法文章笔记以算法、案例为驱动的学习&#xff0c;伴随浅显易懂的数学知识&#xff0c;让大家掌握机器学习常见算法原理&#xff0c;应用Scikit-learn实现机器学习算法的应用&#xff0…

房屋租赁系统的Java实战开发之旅

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

第11章 GUI

11.1 Swing概述 Swing是Java语言开发图形化界面的一个工具包。它以抽象窗口工具包&#xff08;AWT&#xff09;为基础&#xff0c;使跨平台应用程序可以使用可插拔的外观风格。Swing拥有丰富的库和组件&#xff0c;使用非常灵活&#xff0c;开发人员只用很少的代码就可以创建出…

免费申请一个美国EDU学生邮箱

EDU邮箱的作用 例如大名鼎鼎的GitHub学生包。包含各种服务器的优惠卷&#xff0c;可以让你免费使用1-2年的服务器。免费的域名。免费的网站证书。太多了。 微软&#xff1a;免费的5T的OneDrive账户。 Google&#xff1a;G Sutie Drive无限容量 微软、苹果、AWS、都有针对学…

二叉树前序中序后序遍历(非递归)

大家好&#xff0c;又和大家见面啦&#xff01;今天我们一起去看一下二叉树的前序中序后序的遍历&#xff0c;相信这个对大家来说是信手拈来&#xff0c;但是&#xff0c;今天我们并不是使用常见的递归方式来解题&#xff0c;我们采用迭代方式解答。我们先看第一道前序遍历 1…

CCF编程能力等级认证GESP—C++6级—20231209

CCF编程能力等级认证GESP—C6级—20231209 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)闯关游戏工作沟通 答案及解析单选题判断题编程题1编程题2 单选题…

js中数字精度丢失问题详解(如何解决)

文章目录 一、场景复现二、浮点数三、问题分析小结 四、解决方案参考文献 一、场景复现 一个经典的面试题 0.1 0.2 0.3 // false为什么是false呢? 先看下面这个比喻 比如一个数 130.33333333...... 3会一直无限循环&#xff0c;数学可以表示&#xff0c;但是计算机要存…

mysql 2-17

UNION关键字和UNION ALL 自然连接 USING使用 函数 单行函数 基本函数 三角函数 指数和对数 进制间的转换 字符串函数 时间和日期函数 计算日期和时间的函数 日期的格式化和解析 流程控制函数

《剑指 Offer》专项突破版 - 面试题 47 : 二叉树剪枝(C++ 实现)

题目链接&#xff1a;LCR 047. 二叉树剪枝 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 一棵二叉树的所有节点的值要么是 0 要么是 1&#xff0c;请剪除该二叉树中所有节点的值全都是 0 的子树。例如&#xff0c;在剪除下图 (a) 中二叉树中所有节点值都为 0 的…

【NI-DAQmx入门】处理数据采集和测试系统中噪声的几种主要方法

在实际的测试系统中测量模拟信号并不总是像将信号源连接到测量设备那么简单。数据完整性取决于被控制和监视的电气设备发送和接收的干净的电信号。 电噪声可能会掩盖电信号并使其无法识别&#xff0c;从而损害原本具备功能的 DAQ 系统。数据采集​​是关键任务应用测试系统的一…

C++模板详解 —— 函数模板与类模板

C模板详解 泛型编程函数模板函数模板的概念函数模板的原理 函数模板的实例化函数模板的匹配原则类模板类模板的定义格式类模板的实例化 泛型编程 如果让你编写一个函数&#xff0c;用于两个数的交换。在C语言中&#xff0c;我们会用如下方法&#xff1a; void Swapi(int* p1,…

在PyTorch中,如何查看深度学习模型的每一层结构?

这里写目录标题 1. 使用print(model)2. 使用torchsummary库3.其余方法&#xff08;可以参考&#xff09; 在PyTorch中&#xff0c;如果想查看深度学习模型的每一层结构&#xff0c;可以使用print(model)或者model.summary()&#xff08;如果你使用的是torchsummary库&#xff0…