比赛链接
A
一直读不懂题 (天哪我当时怎么想的
排个序\(a_{max} > b_{min}\)就凉了
不然的话 用最多的那个去取升序的\(b_2 ~ b_m\)
\(b_1\)特判一下就好了 (如果都取未必满足\(a_n\)的条件
B
奇妙的构造题
如果\(n \geq (3 * k - 4)\) 显然你可以用1111..(k - 2 + x个1)..10111..(k - 2 + x个1)..111011..(k - 2个1)..111来构造
如果\(n \leq (3 * k - 6)\)的话 就用1111..(x个1)..10111..(x个1)..1110....这样的循环节来构造
其中\(x = \frac{n - k}{2}\)
因为这时候最靠后的一个(k - 1)长度子串种类的第一个起始串位于x + 1 也就是以0开始的那个
然后第二次出现的结束位置就是\(x + 1 + x + 1 + k - 2\)
由于\(x = \frac{n - k}{2}\) 那么就是\(x + 1 + x + 1 + k - 2 = n - k + k = n\)
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 5;
int n, m;
int main(){
scanf("%d%d", &n, &m);
if(n == m){
for(int i = 1; i <= n; ++i) putchar('1');
return 0;
}
int k = ((n - m) >> 1);
for(int i = 1, j = k; i <= n; ++i){
if(j) putchar('1'), --j;
else putchar('0'), j = k;
}
return 0;
}
C
一个合法的nxt树。。
感性理解一下就是你把它的树边画在数轴同侧 树边两两没有交点
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5 + 5;
int n, a[N], nxt[N], cnt;
int dfs(int x){
int i = x;
while(i > 1 && (nxt[i - 1] == x || nxt[i - 1] == -1))
i = dfs(i - 1);
a[x] = ++cnt;
return i;
}
int main()
{
int T; scanf("%d", &T);
while(T--){
scanf("%d", &n); cnt = 0;
for(int i = 1; i <= n; ++i) scanf("%d", &nxt[i]);
if(dfs(n + 1) > 1) printf("-1\n");
else{
for(int i = 1; i <= n; ++i) printf("%d ", a[i]);
printf("\n");
}
}
return 0;
}