2025-03-13~22 hetao1733837 的刷题记录

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();
}
相关推荐
sqyno1sky2 小时前
C++中的契约编程
开发语言·c++·算法
优化控制仿真模型2 小时前
2026年最新驾考科目一考试题库2309道全。电子版pdf
经验分享·算法·pdf
qq_334903152 小时前
嵌入式C++驱动开发
开发语言·c++·算法
阿贵---2 小时前
C++代码规范化工具
开发语言·c++·算法
暮冬-  Gentle°2 小时前
自定义内存检测工具
开发语言·c++·算法
ccLianLian3 小时前
数论·欧拉函数
数据结构·算法
2501_945424803 小时前
C++编译期矩阵运算
开发语言·c++·算法
2301_815482933 小时前
C++中的类型标签分发
开发语言·c++·算法
xushichao19893 小时前
代码生成优化技术
开发语言·c++·算法