2025-03-13~03-22 hetao1733837 的刷题记录
03-15
CF2185D OutOfMemoryError
原题链接:D. OutOfMemoryError
分析
尝试离线做法中...
读错题意了?不是一样的吗?
我还是认为是一样的。
正解
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int t;
int n, m, h, a[N], sum[N], ti[N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t--){
cin >> n >> m >> h;
for (int i = 1; i <= n; i++){
cin >> a[i];
sum[i] = ti[i] = 0;
}
int lst = 0;
for (int i = 1, b, c; i <= m; i++){
cin >> b >> c;
if (ti[b] <= lst){
sum[b] = 0;
}
sum[b] += c;
ti[b] = i;
if (a[b] + sum[b] > h){
lst = i;
}
}
for (int i = 1; i <= n; i++){
if (ti[i] <= lst){
sum[i] = 0;
}
cout << a[i] + sum[i] << " ";
}
cout << '\n';
}
}
CF2185E The Robotic Rush
原题链接:E. The Robotic Rush
分析
套个二分?
我俩写的不是差不多吗?
正解
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
const int INF = 2e9;
int t;
int n, m, k, a[N], b[N], L[N], R[N], cnt[N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t--){
memset(cnt, 0, sizeof(cnt));
memset(L, 0, sizeof(L));
memset(R, 0, sizeof(R));
cin >> n >> m >> k;
for (int i = 1; i <= n; i++){
cin >> a[i];
}
vector<int> buc;
buc.push_back(INF);
buc.push_back(-INF);
for (int i = 1; i <= m; i++){
cin >> b[i];
buc.push_back(b[i]);
}
sort(buc.begin(), buc.end());
string s;
cin >> s;
int x = 0;
for (int i = 1; i <= k; i++){
x += (s[i - 1] == 'R' ? 1 : -1);
L[i] = max(L[i - 1], -x);
R[i] = max(R[i - 1], x);
}
auto solve = [&](int pos){
int res = k + 1;
int p = *lower_bound(buc.begin(), buc.end(), pos);
int l = 1, r = k, mid;
while (l < r){
mid = (l + r) >> 1;
if (pos + R[mid] >= p){
r = mid;
}
else{
l = mid + 1;
}
}
if (pos + R[l] == p){
res = min(res, l);
}
p = *(upper_bound(buc.begin(), buc.end(), pos) - 1);
l = 1, r = k;
while (l < r){
mid = (l + r) >> 1;
if (pos - L[mid] <= p){
r = mid;
}
else{
l = mid + 1;
}
}
if (pos - L[l] == p){
res = min(res, l);
}
cnt[res]++;
};
for (int i = 1; i <= n; i++){
solve(a[i]);
}
int res = n;
for (int i = 1; i <= k; i++){
res -= cnt[i];
cout << res << " ";
}
cout << '\n';
}
return 0;
}
CF1750D Count GCD
原题链接:D. Count GCD
分析
想到了一些东西,不知道对不对。就是,先让 a i a_i ai 彼此互质,然后一点一点往上乘即可。但是,具体怎么把一些部分容斥掉我没想好。
所以,绿题还是没法迈过去......
正解
cpp
#include <bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
const int N = 200005;
int t, n, m, a[N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> t;
while (t--){
cin >> n >> m;
bool flag = true;
for (int i = 1; i <= n; i++){
cin >> a[i];
if (i > 1){
if (a[i - 1] % a[i] != 0){
flag = false;
}
}
}
if (!flag){
cout << 0 << '\n';
continue;
}
int ans = 1;
for (int i = 2; i <= n; i++){
int d = a[i - 1] / a[i];
int x = m / a[i];
int y = 0;
vector<int> arr;
int td = d;
for (int j = 2; j * j <= td; j++){
if (td % j == 0){
int len = arr.size();
for (int k = 0; k < len; k++){
arr.push_back(-arr[k] * j);
}
arr.push_back(j);
while (td % j == 0) td /= j;
}
}
if (td > 1){
int len = arr.size();
for (int k = 0; k < len; k++){
arr.push_back(-arr[k] * td);
}
arr.push_back(td);
}
for (auto val : arr){
y += x / val;
}
ans = ans * (x - y) % mod;
}
cout << ans << '\n';
}
return 0;
}
03-22
LGP3376 【模板】网络最大流
原题链接:【模板】网络最大流
分析
并非理解......
正解
cpp
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 205, M = 5005;
const int INF = 0x7f7f7f7f;
int n, m, s, t;
struct edge{
int frm, nxt, to, val;
}e[M << 1];
int tot = 1, head[N];
void add(int x, int y, int z){
tot++;
e[tot].frm = x;
e[tot].to = y;
e[tot].val = z;
e[tot].nxt = head[x];
head[x] = tot;
}
int cur[M << 1], pre[M << 1];
int de[M << 1], gap[M << 1];
void bfs(){
memset(de, 0, sizeof(de));
memset(gap, 0, sizeof(gap));
de[t] = 1;
queue<int> q;
q.push(t);
while (!q.empty()){
int u = q.front();
q.pop();
gap[de[u]]++;
for (int i = head[u]; i > 0; i = e[i].nxt){
int v = e[i].to;
if (e[i ^ 1].val && de[v] == 0){
de[v] = de[u] + 1;
q.push(v);
}
}
}
}
int Augment(){
int v = t, flow = INF;
while (v != s){
int u = pre[v];
if (e[u].val < flow)
flow = e[u].val;
v = e[u].frm;
}
v = t;
while (v != s){
int u = pre[v];
e[u].val -= flow;
e[u ^ 1].val += flow;
v = e[u].frm;
}
return flow;
}
void ISAP(){
bfs();
int flow = 0;
int u = s;
memcpy(cur, head, sizeof(head));
while (de[s] <= n){
if (u == t){
flow += Augment();
u = s;
}
bool flag = false;
for (int i = cur[u]; i; i = e[i].nxt){
int v = e[i].to;
if (e[i].val && de[v] + 1 == de[u]){
flag = true;
pre[v] = i;
cur[u] = i;
u = v;
break;
}
}
if (!flag){
if (!--gap[de[u]])
break;
int mnde = n + 10;
for (int i = head[u]; i; i = e[i].nxt){
int v = e[i].to;
if (de[v] < mnde && e[i].val){
mnde = de[v];
}
}
de[u] = mnde + 1;
gap[de[u]]++;
cur[u] = head[u];
if (u != s)
u = e[pre[u]].frm;
}
}
cout << flow;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> s >> t;
for (int i = 1, u, v, w; i <= m; i++){
cin >> u >> v >> w;
add(u, v, w);
add(v, u, 0);
}
ISAP();
}
LGP2472 [SCOI2007] 蜥蜴
原题链接:[SCOI2007] 蜥蜴
分析
注意到这个图很小,所以可以(打表)把每只蜥蜴🦎看成源点?找其到边界的最大流是不是小于 d d d ?但是,石柱下降怎么解释?
哦,换个视角,把 石柱高度看成可通过次数 ,把题目看成 网格种若干起点限制步长可以有几个起点走出网格 。
最多 可以想到最大流......好吧,我学艺不精。
发现,可以把每个点都拆成入点和出点,两点之间就是流量,然后开一个虚的总源点,总汇点,做完了。然后存在一个距离的欧几里得路径图,特判一下即可。套一个 Dinic 吧。
正解
cpp
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 25, M = 50005;
const int INF = 0x7f7f7f7f;
char m1[N][N], m2[N][N];
struct edge{
int frm, nxt, to, val;
}e[M];
int tot = 1, head[M];
void add_edge(int x, int y, int z){
tot++;
e[tot].frm = x;
e[tot].to = y;
e[tot].val = z;
e[tot].nxt = head[x];
head[x] = tot;
}
void add(int x, int y, int z){
add_edge(x, y, z);
add_edge(y, x, 0);
}
int n, m, s, t;
int getnum(int i, int j){
return (i - 1) * m + j;
}
int d, all, ans;
void link_edge(int u, int i, int j){
if (i < 1 || i > n || j < 1 || j > m){
add(u, t, INF);
return ;
}
if (m1[i][j] == '0')
return ;
add(u, getnum(i, j), INF);
return ;
}
void link(int i, int j){
if (m1[i][j] == '0')
return ;
add(getnum(i, j), getnum(i, j) + all, m1[i][j] - '0');
if (m2[i][j] == 'L'){
add(s, getnum(i, j), 1);
ans++;
}
if (i == 1 || j == 1 || i == n || j == m){
add(getnum(i, j) + all, t, INF);
}
int u = getnum(i, j) + all;
if (d >= 1){
link_edge(u, i - 1, j);
link_edge(u, i + 1, j);
link_edge(u, i, j - 1);
link_edge(u, i, j + 1);
}
if (d >= 2){
link_edge(u, i - 2, j);
link_edge(u, i + 2, j);
link_edge(u, i, j - 2);
link_edge(u, i, j + 2);
link_edge(u, i - 1, j - 1);
link_edge(u, i - 1, j + 1);
link_edge(u, i + 1, j - 1);
link_edge(u, i + 1, j + 1);
}
if (d >= 3){
link_edge(u, i - 3, j);
link_edge(u, i + 3, j);
link_edge(u, i, j - 3);
link_edge(u, i, j + 3);
link_edge(u, i - 2, j - 2);
link_edge(u, i - 2, j + 2);
link_edge(u, i + 2, j - 2);
link_edge(u, i + 2, j + 2);
link_edge(u, i - 1, j - 2);
link_edge(u, i - 1, j + 2);
link_edge(u, i + 1, j - 2);
link_edge(u, i + 1, j + 2);
link_edge(u, i - 2, j - 1);
link_edge(u, i - 2, j + 1);
link_edge(u, i + 2, j - 1);
link_edge(u, i + 2, j + 1);
}
if (d >= 4){
link_edge(u, i - 4, j);
link_edge(u, i + 4, j);
link_edge(u, i, j - 4);
link_edge(u, i, j + 4);
link_edge(u, i - 1, j - 3);
link_edge(u, i - 1, j + 3);
link_edge(u, i + 1, j - 3);
link_edge(u, i + 1, j + 3);
link_edge(u, i - 3, j - 1);
link_edge(u, i - 3, j + 1);
link_edge(u, i + 3, j - 1);
link_edge(u, i + 3, j + 1);
link_edge(u, i - 2, j - 3);
link_edge(u, i - 2, j + 3);
link_edge(u, i + 2, j - 3);
link_edge(u, i + 2, j + 3);
link_edge(u, i - 3, j - 2);
link_edge(u, i - 3, j + 2);
link_edge(u, i + 3, j - 2);
link_edge(u, i + 3, j + 2);
}
return ;
}
int cur[M], de[M];
queue<int> q;
bool check(){
memset(de, 0, sizeof(de));
de[s] = 1;
q.push(s);
while (!q.empty()){
int u = q.front();
q.pop();
for (int i = head[u]; i; i = e[i].nxt){
int v = e[i].to;
if (e[i].val && !de[v]){
de[v] = de[u] + 1;
q.push(v);
}
}
}
return (de[t] != 0);
}
int dfs(int u, int w){
if (u == t){
return w;
}
int sum = 0;
for (int &i = cur[u]; i; i = e[i].nxt){
int v = e[i].to;
if (e[i].val && de[v] == de[u] + 1){
int tmp = dfs(v, min(w, e[i].val));
if (tmp){
w -= tmp;
sum += tmp;
e[i].val -= tmp;
e[i ^ 1].val += tmp;
if (w <= 0){
return sum;
}
}
}
}
return sum;
}
void Dinic(){
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
link(i, j);
}
}
while (check()){
memcpy(cur, head, sizeof(head));
ans -= dfs(s, INF);
}
cout << ans;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> d;
t = n * m * 2 + 1;
all = n * m;
for (int i = 1; i <= n; i++){
cin >> m1[i] + 1;
}
for (int i = 1; i <= n; i++){
cin >> m2[i] + 1;
}
Dinic();
}