The 4th Universal Cup. Stage 8: Grand Prix of Poland
Preface
不知道 VP 什么还是选了这赛季的外国场 UCUP,毕竟还是正规区域赛题目质量还是有保障的
就是整体难度相对偏低,签到和前期题比较多,同时算法题相对较少,不过这些问题也是老生常谈了
A. AIMPPZ
签到,枚举有几个 AI 即可
#include<cstdio>
#include<iostream>
using namespace std;
int n;
int main()
{
scanf("%d",&n);
int fact_5=0,tmp=n;
while (tmp%5==0) ++fact_5,tmp/=5;
int ans=n,times=0; tmp=1;
for (int i=1;i<=fact_5;++i)
{
tmp*=5;
if (2*i>n/tmp) continue;
if (n/tmp<ans) ans=n/tmp,times=i;
}
for (int i=1;i<=times;++i)
printf("AI");
for (int i=1;i<=ans-2*times;++i)
printf("B");
return 0;
}
B. Beats
考虑枚举一段前缀,钦定除了这段前缀外的后缀全部用第二种操作,此时只要求出需要多少次第一种操作能给前缀排序
手玩一下会发现拿个队列维护一下可以不动的元素即可
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n, A[N];
int que[N], fr=0, ed=-1;
signed main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> n;
int ans = n;
for (int i=1; i<=n; ++i) cin >> A[i];
for (int i=1; i<=n; ++i) {
if (ed<fr || A[i]>que[ed]) que[++ed]=A[i];
else {
while (fr<=ed && A[i]>que[fr]) ++fr;
}
ans = min(ans, n-(ed-fr+1));
}
cout << ans << '\n';
return 0;
}
C. Count Triangular Sequences
直接对 \(\{a_i\}\) 计数比较困难,我们考虑对其差分数组进行计数
令 \(d_i=a_i-(a_{i-1}+a_{i-2})\),特别地,\(d_1=a_1,d_2=a_2-a_1\)
手玩一会我们会发现对于 \(i\ge 3\),满足 \(a_i=\sum_{j=1}^n fib_j\times d_{i+1-j}\),其中 \(fib\) 是以 \(1\) 开头的斐波那契数列
因此这个题本质上就变成一个类似于背包的问题,不难发现由于 \(a_i\le 200000\),因此序列长度 \(\le 28\),用一个类似于完全背包的东西计数即可
注意要特判序列开头两个元素相同的情形
#include<cstdio>
#include<iostream>
#include<cstring>
#define RI register int
#define CI const int&
using namespace std;
const int N=200005,mod=1e9+7,inv2=(mod+1)/2;
int n,fib[30],fact[30],f[30][N];
inline void inc(int& x,CI y)
{
if ((x+=y)>=mod) x-=mod;
}
inline void dec(int& x,CI y)
{
if ((x-=y)<0) x+=mod;
}
int main()
{
scanf("%d",&n);
int pw=n,ans=0; fact[0]=1;
for (RI i=1;i<=n;++i,pw=1LL*pw*n%mod) inc(ans,pw);
int m; fib[0]=0; fib[1]=1;
for (RI i=2;;++i)
{
fib[i]=fib[i-1]+fib[i-2];
if (fib[i]>n) { m=i; break; }
}
for (RI i=1;i<=m;++i) fact[i]=1LL*fact[i-1]*i%mod;
// printf("m = %d\n",m);
f[1][0]=1;
for (RI i=1;i<=min(n,m);++i)
for (RI j=0;j<=n;++j)
{
if (f[i][j]==0) continue;
inc(f[i+1][j],f[i][j]);
if (j+fib[i]<=n)
{
inc(f[i][j+fib[i]],f[i][j]);
if (j+fib[i]+fib[i-1]<=n)
{
dec(ans,1LL*fact[i]*f[i][j]%mod);
} else
{
dec(ans,1LL*fact[i]*f[i][j]%mod*inv2%mod);
}
}
}
return printf("%d\n",ans),0;
}
E. Enigma
经典势能分析题,考虑直接暴力跑多源最短路,每次增加一个新起点时,当且仅当它能减小其它点的答案时才松弛入队
因为第一次操作后每个点的答案 \(\le 25\),而一个点入队会导致其答案至少减少 \(1\),因此总的入队次数就是 \(25\times 100000\) 级别的
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
#define RI register int
#define CI const int&
using namespace std;
const int N=100000;
int n,dis[N+5],bkt[N+5]; vector <int> v[N+5];
int main()
{
for (RI mask=0;mask<N;++mask)
{
for (RI i=1,base=1;i<=5;++i,base*=10)
{
int d=mask/base%10;
if (d+1<=9) v[mask].push_back(mask+base);
else v[mask].push_back(mask-base*9); // d == 9
if (d-1>=0) v[mask].push_back(mask-base);
else v[mask].push_back(mask+base*9); // d == 0
}
dis[mask]=N; ++bkt[dis[mask]];
}
// for (auto x:v[0]) printf("%d ",x); putchar('\n');
for (scanf("%d",&n);n;--n)
{
char s[10]; scanf("%s",s);
int mask=0;
for (RI i=0;i<5;++i)
mask=mask*10+(s[i]-'0');
queue <int> q; q.push(mask);
auto upt=[&](int& x,CI y)
{
--bkt[x]; x=y; ++bkt[x];
};
upt(dis[mask],0);
while (!q.empty())
{
int now=q.front(); q.pop();
// printf("mask = %d\n",now);
for (auto to:v[now])
{
// printf("to = %d\n",to);
if (dis[to]>dis[now]+1)
{
upt(dis[to],dis[now]+1);
q.push(to);
}
}
}
for (RI i=25;i>=0;--i)
if (bkt[i]!=0)
{
printf("%d %d\n",i,bkt[i]);
break;
}
}
return 0;
}
F. Finances
这题纯队友讨论+写出来的,我题目都没看
#include <bits/stdc++.h>
using llsi = long long signed int;
#define int llsi
constexpr int $n = 1'000'006;
int n, m;
int a[$n];
std::vector<std::tuple<int, llsi, int>> e[$n];
std::vector<std::pair<int, llsi>> e2[$n];
int ecc[$n], ecc_cnt;
llsi ecc_a[$n];
int __edge_cnt = 0;
void add_edge(int u, int v, llsi c) {
e[u].emplace_back(v, c, __edge_cnt++);
e[v].emplace_back(u, c, __edge_cnt++);
}
namespace Tarjan {
int low[$n], dfn[$n];
std::stack<int> st;
std::vector<std::tuple<int, int, llsi>> bdg;
int cnt;
void tarjan(int x, std::tuple<int, llsi, int> be) {
auto [fa, c, las_id] = be;
low[x] = dfn[x] = ++cnt;
st.push(x);
for(auto [out, cc, id]: e[x]) {
if(id == las_id) continue;
if(!dfn[out]) {
tarjan(out, {x, cc, id ^ 1});
low[x] = std::min(low[x], low[out]);
} else {
low[x] = std::min(low[x], dfn[out]);
}
}
if(dfn[x] == low[x]) {
ecc[x] = ++ecc_cnt;
ecc_a[ecc_cnt] += a[x];
while(st.top() != x) {
ecc[st.top()] = ecc_cnt;
ecc_a[ecc_cnt] += a[st.top()];
st.pop();
}
st.pop();
if(fa != -1) bdg.emplace_back(x, fa, c);
}
}
}
void init() {
__edge_cnt = 0;
Tarjan::cnt = 0;
Tarjan::bdg.clear();
ecc_cnt = 0;
for(int i = 0; i <= n; ++i) {
e[i].clear();
e2[i].clear();
Tarjan::low[i] = 0;
Tarjan::dfn[i] = 0;
ecc_a[i] = 0;
}
}
std::pair<bool, llsi> dfs(int cur, int fa, llsi c) {
// std::cerr << std::format("dfs({} {} {})", cur, fa, c) << char(10);
llsi sum = ecc_a[cur];
for(auto [out, cc]: e2[cur]) if(out != fa) {
auto [res_out, sum_out] = dfs(out, cur, cc);
if(!res_out) return { false, 0 };
sum += sum_out;
}
return { std::abs(sum) <= c, sum };
}
bool work() {
std::cin >> n >> m;
init();
for(int i = 1; i <= n; ++i) std::cin >> a[i];
for(int i = 1, u, v; i <= m; ++i) {
llsi c;
std::cin >> u >> v >> c;
add_edge(u, v, c);
}
Tarjan::tarjan(1, {-1, -1, -1});
// for(int i = 1; i <= n; ++i) std::cerr << ecc[i] << char(i == n ? 10 : 32);
for(auto [u, v, c]: Tarjan::bdg) {
e2[ecc[u]].emplace_back(ecc[v], c);
e2[ecc[v]].emplace_back(ecc[u], c);
}
return dfs(1, 0, 0).first;
}
int32_t main() {
std::ios::sync_with_stdio(false);
int T; std::cin >> T; while(T--) std::cout << (work() ? "TAK\n" : "NIE\n");
return 0;
}
H. Hacking
签到,我题都没看
#include <bits/stdc++.h>
int main() {
int n; std::cin >> n;
int sum = 0;
while(n--) { int a; std::cin >> a; sum += a; }
std::cout << 600 - sum << char(10);
return 0;
}
I. ICPC Isolation
爆搜+打表,真是公公又式式
#include <bits/stdc++.h>
const char* UNAME[27] = { "UW", "UJ", "UWR", "MAP", "PW", "AGH", "PG", "NLU", "PUT", "PO", "PWR", "SGGW", "UMCS", "UR", "ZUT", "DTP", "GOO", "HUA", "KUL", "PL", "PM", "PS", "UAM", "UG", "UMK", "UO", "WAT" };
int UCOUNT[27] = { 11 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 3 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 };
extern int ans[27][8][10];
void print_table(const std::string &prefix, int ans[8][10]) {
std::cout << " // " << prefix << char(10);
for(int i = 0; i < 8; ++i) {
std::cout << " ";
for(int j = 0; j < 10; ++j)
std::cout << std::setw(2) << ans[i][j] << ",",
std::cout << char(j == 9 ? 10 : 32);
}
}
void print_ans() {
std::cout << "int ans[27][8][10] = {\n";
for(int k = 0; k < 27; ++k)
print_table(std::format("ars = {} ({})", k, UNAME[k]), ans[k]);
std::cout << "};\n";
return ;
}
bool dfs(int ans[8][10], int i, int j) {
if(i == 8) return true;
// std::cerr << "[dfs] i, j = " << i << ", " << j << char(10);
int ni = i, nj = j + 1;
if(nj == 10) nj = 0, ni += 1;
for(int cl = 0; cl < 27; ++cl) if(UCOUNT[cl]) {
bool res = false;;
for(auto [si, sj]: (int[4][2]){{i - 1, j - 1}, {i - 1, j}, {i - 1, j + 1}, {i, j - 1}}) {
if(si < 0 || si >= 8) continue;
if(sj < 0 || sj >= 10) continue;
if(cl == ans[si][sj]) goto __continue__;
}
UCOUNT[cl]--; ans[i][j] = cl;
res = dfs(ans, ni, nj);
UCOUNT[cl]++;
if(res) return true;
__continue__: continue;
}
return false;
}
void prep_ans() {
for(int ars = 0; ars < 27; ++ars) {
std::cerr << "Calculate ans for (ars = " << ars << ")" << std::endl;
ans[ars][0][0] = ars;
UCOUNT[ars]--;
dfs(ans[ars], 0, 1);
UCOUNT[ars]++;
}
}
int main() {
std::ios::sync_with_stdio(false);
// memset(ans, -1, sizeof(ans));
// prep_ans();
// print_ans();
// return 0;
std::string ars; std::cin >> ars;
int k;
for(k = 0; k < 27; ++k) if(ars == UNAME[k]) break;
assert(k < 27);
for(int i = 0; i < 8; ++i) for(int j = 0; j < 10; ++j)
std::cout << UNAME[ans[k][i][j]] << char(j == 9 ? 10 : 32);
return 0;
}
int ans[27][8][10] = {
// ars = 0 (UW)
0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
0, 1, 0, 1, 0, 1, 0, 1, 0, 4,
2, 3, 2, 3, 2, 4, 5, 4, 5, 6,
0, 4, 5, 4, 5, 6, 7, 6, 7, 4,
5, 6, 7, 8, 9, 8, 9, 8, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 1 (UJ)
1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
0, 1, 0, 1, 0, 1, 0, 1, 0, 4,
2, 3, 2, 3, 2, 4, 5, 4, 5, 6,
0, 4, 5, 4, 5, 6, 7, 6, 7, 4,
5, 6, 7, 8, 9, 8, 9, 8, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 2 (UWR)
2, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 3, 2, 3, 2, 3, 2, 3, 2, 3,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 4, 5, 4, 5, 4,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 8, 9, 8, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 3 (MAP)
3, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 4, 5, 4, 5, 4,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 8, 9, 8, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 4 (PW)
4, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 8, 9, 8, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 5 (AGH)
5, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
6, 7, 8, 9, 8, 4, 8, 9, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 6 (PG)
6, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 7, 8, 9, 8, 4, 8, 9, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 7 (NLU)
7, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 8, 9, 8, 4, 8, 9, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 8 (PUT)
8, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 10, 11,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 9 (PO)
9, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 10, 8, 10,
11, 12, 11, 12, 13, 14, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 10 (PWR)
10, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
11, 12, 11, 12, 13, 14, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 11 (SGGW)
11, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 13, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 12 (UMCS)
12, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 13, 14, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 13 (UR)
13, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 15, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 14 (ZUT)
14, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 15 (DTP)
15, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 16 (GOO)
16, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 17 (HUA)
17, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 18, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 18 (KUL)
18, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 19, 20, 21, 22, 23, 24, 25, 26,
// ars = 19 (PL)
19, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 20, 21, 22, 23, 24, 25, 26,
// ars = 20 (PM)
20, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 19, 21, 22, 23, 24, 25, 26,
// ars = 21 (PS)
21, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 19, 20, 22, 23, 24, 25, 26,
// ars = 22 (UAM)
22, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 19, 20, 21, 23, 24, 25, 26,
// ars = 23 (UG)
23, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 24, 25, 26,
// ars = 24 (UMK)
24, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 25, 26,
// ars = 25 (UO)
25, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 26,
// ars = 26 (WAT)
26, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 2, 3, 2, 3, 2, 3, 2, 3, 2,
0, 4, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 4, 5, 4, 5,
0, 4, 5, 4, 5, 6, 7, 6, 7, 6,
5, 6, 7, 8, 9, 4, 8, 9, 8, 10,
10, 11, 12, 11, 12, 13, 14, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
};
J. Jury of AMPPZ
考虑二分答案 \(x\),则贪心地让计算几何题里 \((val,id)\) 二元组最大的那 \(x\) 个进入前 \(k\) 名一定最优
要最大化它们的最小值,只需要从小到大排序后依次加上 \(n,n-1,\ldots,n-x+1\) 即可
对于非计算几何题,前 \(k-x\) 大的元素其实可以忽略不管,我们只要保证上面的最小值能超过剩下题的最大值即可
还是如法炮制地贪心,从大到小排序后依次加上 \(1,2,\ldots\) 即可,最后求个最大值和前面比较一下
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#define RI register int
#define CI const int&
using namespace std;
int n,k; vector <pair <int,int>> A,B;
int main()
{
scanf("%d%d",&n,&k);
for (RI i=1;i<=n;++i)
{
int x,a,b,c,d;
scanf("%d%d%d%d%d",&x,&a,&b,&c,&d);
if (x==1) A.push_back({a+b+c+d,-i});
else B.push_back({a+b+c+d,-i});
}
sort(A.begin(),A.end(),greater <pair <int,int>>());
sort(B.begin(),B.end(),greater <pair <int,int>>());
int l=1,r=min(k,(int)A.size()),mid,res=0;
auto check=[&](CI x)
{
pair <int,int> mn={1e9,0};
for (RI i=0;i<x;++i)
mn=min(mn,{A[i].first+n-x+1+i,A[i].second});
for (RI i=k-x;i<(int)B.size();++i)
if (mn<make_pair(B[i].first+i-(k-x)+1,B[i].second)) return false;
return true;
};
while (l<=r)
if (check(mid=l+r>>1)) res=mid,l=mid+1; else r=mid-1;
return printf("%d\n",res),0;
}
K. Kids' Blocks
又是个我没看题的签到
#include <bits/stdc++.h>
constexpr int $n = 300'005;
int a[$n], pm[$n], sm[$n];
int main() {
std::ios::sync_with_stdio(false);
int n; std::cin >> n;
for(int i = 1; i <= n; ++i) std::cin >> a[i];
pm[1] = a[1]; for(int i = 2; i <= n; ++i) pm[i] = std::max(pm[i - 1], a[i]);
sm[n] = a[n]; for(int i = n - 1; i >= 1; --i) sm[i] = std::max(sm[i + 1], a[i]);
int ans = 0x7fff'ffff;
for(int i = 1; i < n; ++i) ans = std::min(ans, std::abs(sm[i + 1] - pm[i]));
std::cout << ans << char(10);
return 0;
}
L. Linear Averaging
我去蹲了个坑队友就会这个题了,好像是个转化成几何问题后用 convex trick 搞一搞的题,只能说队友太有实力
#include <bits/stdc++.h>
using llsi = long long signed int;
using ldb = long double;
#define double ldb
constexpr int $n = 500005;
int n, m, k;
int a[$n];
llsi sum_k[$n];
llsi pos[$n], neg[$n], ans[$n];
double ans1[$n], ans2[$n];
void solve(double ans[$n]) {
std::vector<std::pair<double, double>> lines;
for(llsi i = 1; i <= m; ++i) {
if(pos[i] >= 0) {
double K = double(pos[i]);
double B = double(i);
if(K == 0) {
ans[i] = 0.0L;
continue;
}
while(lines.size() && K >= lines.back().first) lines.pop_back();
while(lines.size() >= 2) {
auto [K1, B1] = lines[lines.size() - 1];
auto [K2, B2] = lines[lines.size() - 2];
auto Y1 = (K1 * B2 - K2 * B1) / (K1 - K2);
auto Y2 = (K1 * B - K * B1) / (K1 - K );
if(Y2 <= Y1) break;
lines.pop_back();
}
lines.emplace_back(K, B);
}
while(lines.size() >= 2) {
auto [K1, B1] = lines[lines.size() - 1];
auto [K2, B2] = lines[lines.size() - 2];
if((K1 * B2 - K2 * B1) / (K1 - K2) >= i) break;
lines.pop_back();
}
// std::cerr << "[DEBUG solve() i = " << i << "] lines:";
// if(lines.empty()) std::cerr << " [empty]";
// else for(auto [K, B]: lines) std::cerr << " (" << K << ", " << B << ")";
// std::cerr << char(10);
if(lines.size()) {
auto [K, B] = lines.back();
ans[i] = ((double)i - B) / (K / k);
} else {
ans[i] = 1e16;
}
// std::cerr << "ans[" << i << "] = " << ans[i] << char(10);
}
}
const char* clip(llsi a, llsi INF) {
if(a >= INF) return "INF";
if(a <= -INF) return "NNF";
static char ss[40];
std::sprintf(ss, "%lld", a);
return ss;
}
int main() {
std::ios::sync_with_stdio(false);
std::cerr << std::fixed << std::setprecision(2);
std::cin >> n >> m >> k;
for(int i = 1; i <= n; ++i) std::cin >> a[i];
/* prep sum_k */ {
llsi s = 0;
for(int i = 1; i < k; ++i) s += a[i];
for(int i = k; i <= n; ++i) {
s += a[i];
sum_k[i - k + 1] = s;
s -= a[i - k + 1];
}
}
std::deque<int> q_pos, q_neg;
for(int i = 1; i <= m; ++i)
pos[i] = -4e18,
neg[i] = 4e18;
for(int i = 1; i <= n; ++i)
pos[a[i]] = llsi(k) * llsi(a[i]),
neg[a[i]] = llsi(k) * llsi(a[i]);
for(int i = 1; i <= n; ++i) {
if(i + k - 1 <= n) {
while(q_pos.size() && sum_k[i] >= sum_k[q_pos.back()]) q_pos.pop_back();
while(q_neg.size() && sum_k[i] <= sum_k[q_neg.back()]) q_neg.pop_back();
q_pos.push_back(i);
q_neg.push_back(i);
}
while(q_pos.size() && q_pos.front() + k - 1 < i) q_pos.pop_front();
while(q_neg.size() && q_neg.front() + k - 1 < i) q_neg.pop_front();
pos[a[i]] = std::max(pos[a[i]], sum_k[q_pos.front()]);
neg[a[i]] = std::min(neg[a[i]], sum_k[q_neg.front()]);
}
for(llsi i = 1; i <= m; ++i)
pos[i] -= i * k,
neg[i] -= i * k;
solve(ans1);
for(int i = 1; i <= m; ++i) pos[i] = -neg[m - i + 1];
solve(ans2);
// std::cerr << "[DEBUG] pos[]: "; for(int i = 1; i <= m; ++i) std::cerr << clip(pos[i], 100000) << char(i == m ? 10 : 32);
// std::cerr << "[DEBUG] neg[]: "; for(int i = 1; i <= m; ++i) std::cerr << clip(neg[i], 100000) << char(i == m ? 10 : 32);
// std::cerr << "[DEBUG] ans1[]: "; for(int i = 1; i <= m; ++i) std::cerr << ans1[i] << char(i == m ? 10 : 32);
// std::cerr << "[DEBUG] ans2[]: "; for(int i = 1; i <= m; ++i) std::cerr << ans2[i] << char(i == m ? 10 : 32);
std::cout << std::fixed << std::setprecision(20);
for(int i = 1; i <= m; ++i) {
double ans = std::min(ans1[i], ans2[m - i + 1]);
if(ans < 0.0L || ans > 1.0L) std::cout << "-1\n";
else std::cout << ans << char(10);
}
return 0;
}
Postscript
感觉两天一训强度还是挺大的,不禁让我想起之前每天一训是怎么坚持下来的

浙公网安备 33010602011771号