A
Solved: 03:26(zkp)
zkp今天的锅有点大啊。。开场上来打A,然后2h后说完蛋了。
看完题扔给他了一个DP打表写法
他写完之后说TN^2怎么过啊
嗯??不是打表吗?
-7
太dirt了
#include <bits/stdc++.h>
using namespace std;
int dp[4][4][500][500];
vector<pair<int,int> >r[4][4][500][500];
int main() {
for(int i=0;i<3;i++)for(int j=0;j<3;j++)for(int k=0;k<=200;k++)for(int l=0;l<=200;l++)dp[i][j][k][l]=0;
dp[0][0][0][0]=1;
for(int i=0;i<3;i++)for(int j=0;j<3&&i+j<=4;j++)
{
for(int k=0;k<=200;k++)for(int l=0;l<=200;l++)if(dp[i][j][k][l])
{
for(int m=0;m+k<=200;m++)
if(i+j<4)
{
int n=0;
if(m<23)dp[i][j+1][m+k][l+25]=true,r[i][j+1][m+k][l+25]=r[i][j][k][l],
r[i][j+1][m+k][l+25].push_back(make_pair(m,25));
if(m>=25)dp[i+1][j][m+k][l+m-2]=true,r[i+1][j][m+k][l+m-2]=r[i][j][k][l],
r[i+1][j][m+k][l+m-2].push_back(make_pair(m,m-2));
if(m>=23)dp[i][j+1][m+k][l+m+2]=true,r[i][j+1][m+k][l+m+2]=r[i][j][k][l],
r[i][j+1][m+k][l+m+2].push_back(make_pair(m,m+2));
if(m==25)for(int n=0;n<=23;n++)dp[i+1][j][m+k][l+n]=true,
r[i+1][j][m+k][l+n]=r[i][j][k][l],
r[i+1][j][m+k][l+n].push_back(make_pair(m,n));
}
else
{
int n=0;
if(m<13)dp[i][j+1][m+k][l+15]=true,r[i][j+1][m+k][l+15]=r[i][j][k][l],
r[i][j+1][m+k][l+15].push_back(make_pair(m,15));
if(m>=15)dp[i+1][j][m+k][l+m-2]=true,r[i+1][j][m+k][l+m-2]=r[i][j][k][l],
r[i+1][j][m+k][l+m-2].push_back(make_pair(m,m-2));
if(m>=13)dp[i][j+1][m+k][l+m+2]=true,r[i][j+1][m+k][l+m+2]=r[i][j][k][l],
r[i][j+1][m+k][l+m+2].push_back(make_pair(m,m+2));
if(m==15)for(int n=0;n<=13;n++)dp[i+1][j][m+k][l+n]=true,
r[i+1][j][m+k][l+n]=r[i][j][k][l],
r[i+1][j][m+k][l+n].push_back(make_pair(m,n));
}
}
}
int t;
cin>>t;
while(t--)
{
int a,b;
bool w=true;
cin>>a>>b;
if(dp[3][0][a][b])
{
cout<<"3:0"<<endl;
for(int i=0;i<r[3][0][a][b].size();i++)
cout<<r[3][0][a][b][i].first<<":"<<r[3][0][a][b][i].second<<" ";
cout<<endl;
}
else if(dp[3][1][a][b])
{
cout<<"3:1"<<endl;
for(int i=0;i<r[3][1][a][b].size();i++)
cout<<r[3][1][a][b][i].first<<":"<<r[3][1][a][b][i].second<<" ";
cout<<endl;
}
else if(dp[3][2][a][b])
{
cout<<"3:2"<<endl;
for(int i=0;i<r[3][2][a][b].size();i++)
cout<<r[3][2][a][b][i].first<<":"<<r[3][2][a][b][i].second<<" ";
cout<<endl;
}
else if(dp[2][3][a][b])
{
cout<<"2:3"<<endl;
for(int i=0;i<r[2][3][a][b].size();i++)
cout<<r[2][3][a][b][i].first<<":"<<r[2][3][a][b][i].second<<" ";
cout<<endl;
}
else if(dp[1][3][a][b])
{
cout<<"1:3"<<endl;
for(int i=0;i<r[1][3][a][b].size();i++)
cout<<r[1][3][a][b][i].first<<":"<<r[1][3][a][b][i].second<<" ";
cout<<endl;
}
else if(dp[0][3][a][b])
{
cout<<"0:3"<<endl;
for(int i=0;i<r[0][3][a][b].size();i++)
cout<<r[0][3][a][b][i].first<<":"<<r[0][3][a][b][i].second<<" ";
cout<<endl;
}
else cout<<"Impossible"<<endl;
}
return 0;
}
B
Unsolved
C
Unsolved
D
Unsolved
E
Solved: 02:01 (HOOCCOOH)
#include <iostream>
#include <cassert>
#include <algorithm>
#include <utility>
#include <vector>
auto make_route(int n) {
auto v = std::vector<std::pair<int, int>>();
auto row = [&](int x, int from, int to, int cnt) {
v.emplace_back(x, from);
cnt -= 2;
for(int i = 0; i < 8 && cnt > 0; ++i)
if(i != from && i != to) {
v.emplace_back(x, i);
--cnt;
}
v.emplace_back(x, to);
};
int from = 0;
for(int i = 0; ; ++i)
if(n <= 2)
assert(false);
else if(n <= 9) {
int to = i == 7 ? 6 : 7;
row(i, from, to, n - 1);
v.emplace_back(7, 7);
break;
} else if(n == 10) {
row(i, from, 6, 8);
v.emplace_back(7, 6);
v.emplace_back(7, 7);
break;
} else {
row(i, from, from ^ 1, 8);
from ^= 1;
n -= 8;
}
return v;
}
int main() {
std::ios::sync_with_stdio(false);
int n;
std::cin >> n;
auto steps = make_route(n + 1);
// std::cerr << "<" << steps.size() << ">\n";
for(auto &c: steps)
std::cout
<< (char)('a' + c.second) << c.first + 1
<< ' ';
std::cout << std::endl;
return 0;
}
F
Solved: 01:21 (BPM136)
可以转化为
∑
i
=
1
k
a
i
∗
k
i
=
n
−
1
\sum_{i=1}^{k} a_i*k_i=n-1
∑i=1kai∗ki=n−1
这东西非常不好解
发现这是k元不定方程非常不好解,如果n是一个prime,那么感觉是无解的
否则一定存在一种拆分方案,使得两个因子互素
那么用那两个因子来计算的不定方程一定有解,exgcd即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
int ExGcd(int a, int b, int& x, int& y) {
if (b == 0)
return x = 1, y = 0, a;
int d = ExGcd(b, a % b, x, y);
int z = x;
x = y;
y = z - y * (a / b);
return d;
}
#undef int
int main() {
#define int long long
int n;
cin >> n;
for (int i = 2; i * i <= n; ++i)
if (n % i == 0) {
int a = i, b = n / i;
int x, y;
int d = ExGcd(a, b, x, y);
if ((n - 1) % d)
continue;
x = (x + b / d) * ((n - 1) / d);
x = (x % (b / d) + b / d) % (b / d);
y = (n - 1 - a * x) / b;
puts("YES");
puts("2");
cout << x << ' ' << b << '\n';
cout << y << ' ' << a << '\n';
return 0;
}
puts("NO");
}
G
Solved: 00:32 (BPM136)
对于手残的我不那么温暖的签到然而+了
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int a[100];
int main() {
ios::sync_with_stdio(0);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
for (int i = 0; i < 7; ++i) {
cin >> a[i];
a[i + 7] = a[i];
}
int sum = 0;
for (int i = 0; i < 7; ++i)
sum += a[i];
int ans = 1e9;
for (int i = 0; i < 7; ++i) {
if (n < sum) {
int t = 0;
for (int j = i; j < i + 7; ++j) {
t += a[j];
if (t == n) {
ans = min(ans, j - i + 1);
break;
}
}
} else {
int t = 0;
if (n - (n - 1) / sum * sum == 0) {
ans = min(ans, 7 * ((n - 1) / sum));
continue;
}
for (int j = i; j < i + 7; ++j) {
t += a[j];
if (t == (n - (n - 1) / sum * sum)) {
ans = min(ans, 7 * ((n - 1) / sum) + j - i + 1);
break;
}
}
}
}
cout << ans << '\n';
}
}
H
Unsolved
I
Unsolved
J
Unsolved
K
Solved: 02:13 (BPM136)
即维护l到r区间每个元+i的最大值
就是sum[l][r]+l在r固定时的最大值
#include <bits/stdc++.h>
using namespace std;
int const MAXB = 1000000;
int const n = 1000000;
int const N = 1000000;
using ll = long long;
ll bit[N];
void BITAdd(int x, int y) {
while (x <= MAXB) {
bit[x] += y;
x += x & -x;
}
}
ll BITQuery(int x) {
ll ret = 0;
while (x) {
ret += bit[x];
x -= x & -x;
}
return ret;
}
ll mx[N << 2], lz[N << 2];
void pushup(int k) {
mx[k] = max(mx[k << 1], mx[k << 1 | 1]);
}
void pushdown(int k) {
mx[k << 1] += lz[k];
mx[k << 1 | 1] += lz[k];
lz[k << 1] += lz[k];
lz[k << 1 | 1] += lz[k];
lz[k] = 0;
}
void SegBuild(int k, int l, int r) {
if (l == r) {
lz[k] = 0;
mx[k] = l;
return;
}
int mid = (l + r) >> 1;
SegBuild(k << 1, l, mid);
SegBuild(k << 1 | 1, mid + 1, r);
pushup(k);
}
void SegAdd(int k, int l, int r, int _l, int _r, int val) {
if (l == _l && r == _r) {
lz[k] += val;
mx[k] += val;
return;
}
int mid = (l + r) >> 1;
if (lz[k])
pushdown(k);
if (_r <= mid)
SegAdd(k << 1, l, mid, _l, _r, val);
else if (_l > mid)
SegAdd(k << 1 | 1, mid + 1, r, _l, _r, val);
else
SegAdd(k << 1, l, mid, _l, mid, val),
SegAdd(k << 1 | 1, mid + 1, r, mid + 1, _r, val);
pushup(k);
}
ll SegQuery(int k, int l, int r, int _l, int _r) {
if (l == _l && r == _r)
return mx[k];
int mid = (l + r) >> 1;
if (lz[k])
pushdown(k);
ll ret;
if (_r <= mid)
ret = SegQuery(k << 1, l, mid, _l, _r);
else if (_l > mid)
ret = SegQuery(k << 1 | 1, mid + 1, r, _l, _r);
else {
ll retx = SegQuery(k << 1, l, mid, _l, mid);
ll rety = SegQuery(k << 1 | 1, mid + 1, r, mid + 1, _r);
ret = max(retx, rety);
}
pushup(k);
return ret;
}
int t[N], d[N];
int main() {
ios::sync_with_stdio(0);
SegBuild(1, 1, n);
int T;
cin >> T;
char op;
for (int i = 1; i <= T; ++i) {
cin >> op;
if (op == '+') {
cin >> t[i] >> d[i];
SegAdd(1, 1, n, 1, t[i], d[i]);
BITAdd(t[i], d[i]);
}
if (op == '-') {
int x;
cin >> x;
SegAdd(1, 1, n, 1, t[x], -d[x]);
BITAdd(t[x], -d[x]);
}
if (op == '?') {
int q;
cin >> q;
ll ans = SegQuery(1, 1, n, 1, q) - q - (BITQuery(MAXB) - BITQuery(q));
cout << ans << '\n';
}
}
return 0;
}
L
Solved: 00:11 (BPM136)
温暖的签到
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int const N = 100005;
vector<int> v[N];
int main() {
int n, m;
cin >> n >> m;
static int a[N], b[N];
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i)
cin >> b[i];
for (int i = 1; i <= n; ++i)
v[a[i]].push_back(b[i]);
for (int i = 1; i <= m; ++i)
sort(v[i].begin(), v[i].end(), greater<int>());
auto tot = vector<int>();
int nee = 0;
for (int i = 1; i <= m; ++i) {
if (v[i].size() > 1u)
for (int j = 1; j < v[i].size(); ++j)
tot.push_back(v[i][j]);
if (v[i].size() == 0u)
++nee;
}
sort(tot.begin(), tot.end());
ll ans = 0;
for (int i = 0; i < nee; ++i)
ans += tot[i];
cout << ans << '\n';
return 0;
}
close
M
Upsolved by BPM136
比赛的时候构造是有锅的
我们可以先强联通分量缩点再拓扑排序
每一层一共有3行
长度为边数*2
对于每个强联通分量的点都放在同一层的第3行
前两行如果一个强联通分量到另一个强联通分量有边
那就把对应序号的位置造一堵墙围住
也就是
12345
.#.#.#.#.#.#
.#.#.#.#.#.#
如果围住,那就是
12345
.###.#.###.#
.#.#.#.#.#.#
#include <bits/stdc++.h>
using namespace std;
int const N = 20;
int const M = 200;
struct edge {
int y, next;
}e1[M], e2[M];
int last1[N], last2[N];
int ne1 = 0, ne2 = 0;
bool vis1[N], vis2[N];
void addch(int x, int y) {
e1[++ne1].y = y;
e1[ne1].next = last1[x];
last1[x] = ne1;
e2[++ne2].y = x;
e2[ne2].next = last2[y];
last2[y] = ne2;
}
int st[N];
int belong[N];
int num;
int setNum[N];
int cnt1, cnt2;
int n;
int a[N][N];
void dfs1(int x) {
vis1[x] = 1;
for (int i = last1[x]; i != 0; i = e1[i].next)
if (vis1[e1[i].y] == 0)
dfs1(e1[i].y);
st[cnt1++] = x;
}
void dfs2(int x) {
vis2[x] = 1;
++num;
belong[x] = cnt2;
for (int i = last2[x]; i != 0; i = e2[i].next)
if (vis2[e2[i].y] == 0)
dfs2(e2[i].y);
}
void Kosaraju() {
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (a[i][j])
addch(i, j);
memset(vis1, 0, sizeof(vis1));
memset(vis2, 0, sizeof(vis2));
cnt1 = cnt2 = 0;
for (int i = 1; i <= n; ++i)
if (vis1[i] == 0)
dfs1(i);
for (int i = cnt1 - 1; i >= 0; --i)
if (vis2[st[i]] == 0) {
num = 0;
++cnt2;
dfs2(st[i]);
setNum[cnt2] = num;
}
}
int ma[N][N];
vector<int> TopoSort() {
queue<int> Q;
static int du[N];
memset(du, 0, sizeof(du));
for (int i = 1; i <= cnt2; ++i)
for (int j = 1; j <= cnt2; ++j)
if (ma[i][j])
++du[j];
for (int i = 1; i <= cnt2; ++i)
if (du[i] == 0)
Q.push(i);
auto ret = vector<int>();
while (Q.empty() == 0) {
int now = Q.front();
Q.pop();
ret.push_back(now);
for (int i = 1; i <= cnt2; ++i)
if (ma[now][i] && du[i]) {
--du[i];
if (du[i] == 0)
Q.push(i);
}
}
return ret;
}
int f[N * N][4][N * 2];
void Output(vector<int> &ver) {
int len_x = n * n * 2;
int len_y = 3;
int len_z = 2 * cnt2;
cout << len_x << ' ' << len_y << ' ' << len_z << '\n';
for (int i = 1; i <= cnt2; ++i)
for (int j = 1; j <= len_x; ++j)
for (int k = 1; k <= len_y; ++k)
f[j][k][i * 2 - 1] = -1;
for (int i = 1; i <= cnt2; ++i) {
int fl = cnt2 - i + 1;
fl = fl * 2;
int tmpn = 0;
for (int j = 1; j <= n; ++j)
if (belong[j] == ver[i - 1])
f[++tmpn][3][fl] = j;
for (int j = 1; j <= cnt2 * cnt2; ++j)
f[j * 2][1][fl] = f[j * 2][2][fl] = -1;
}
for (int i = 1; i <= cnt2; ++i)
for (int j = 1; j <= cnt2; ++j)
if (ma[ver[i - 1]][ver[j - 1]]) {
int fl_i = cnt2 - i + 1;
int fl_j = cnt2 - j + 1;
fl_i = fl_i * 2;
fl_j = fl_j * 2;
--fl_i;
++fl_j;
for (int k = fl_j; k <= fl_i; ++k) {
f[((i - 1) * cnt2 + j) * 2 - 1][1][k] = 0;
f[((i - 1) * cnt2 + j) * 2 - 1][2][k] = -1;
}
}
for (int o = len_z; o >= 1; --o) {
for (int j = 1; j <= len_y; ++j) {
for (int i = 1; i <= len_x; ++i) {
if (f[i][j][o] == 0)
cout << '.';
else if (f[i][j][o] == -1)
cout << '#';
else
cout << f[i][j][o];
}
cout << '\n';
}
cout << '\n';
}
}
int main() {
ios::sync_with_stdio(0);
cin >> n;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
cin >> a[i][j];
Kosaraju();
memset(ma, 0, sizeof(ma));
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (a[i][j])
ma[belong[i]][belong[j]] = 1;
for (int i = 1; i <= cnt2; ++i)
ma[i][i] = 0;
auto ver = TopoSort();
Output(ver);
return 0;
}
close