比赛链接
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
");
else{
for(int i = 1; i <= n; ++i) printf("%d ", a[i]);
printf("
");
}
}
return 0;
}
D
在凸包上旋转跳跃 然鹅我不会证。。
#include <bits/stdc++.h>
#define fir first
#define sec second
#define mp(x, y) make_pair(x, y)
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
const int N = 2005;
int n; PLL node[N]; bool vis[N]; char str[N];
inline PLL operator - (PLL x, PLL y){return mp(x.fir - y.fir, x.sec - y.sec);}
inline ll Cross(PLL x, PLL y){return x.fir * y.sec - x.sec * y.fir;}
inline bool Left(int x, int y, int z){
return Cross(node[y] - node[x], node[z] - node[y]) >= 0;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++i){
ll x, y; scanf("%lld%lld", &x, &y); node[i] = mp(x, y);
}
scanf("%s", str + 1);
int cur = 1;
for(int i = 1; i <= n; ++i) if(node[i].fir < node[cur].fir) cur = i;
vis[cur] = 1; printf("%d ", cur);
for(int i = 1, nxt; i <= n - 1; ++i){
nxt = 0;
for(int j = 1; j <= n; ++j) if(!vis[j])
if(nxt) nxt = (Left(cur, nxt, j) ^ (str[i] == 'L')) ? j : nxt;
else nxt = j;
cur = nxt; vis[cur] = 1; printf("%d ", cur);
}
return 0;
}