Polaris.AI Programming Contest 2025(AtCoder Beginner Contest 429)

D - On AtCoder Conference

环形 二分

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f

#define int long long

int n, m, c;
int a[500010];
int s[2*500010];
map<int, int> mp;

void solve(){
    cin >> n >> m >> c;
    vector<int> vec;
    vec.pb(0); vec.pb(m);
    for(int i = 1; i <= n; i ++){
        cin >> a[i];
        vec.pb(a[i]); 
        mp[a[i]] ++;
    }
    sort(vec.begin(), vec.end()); vec.erase(unique(vec.begin(), vec.end()),vec.end());

    int nn = vec.size();
    for(int i = 0; i < nn; i ++) vec.pb(vec[i]);
    for(int i = 0; i < nn + nn; i ++){
        if(i == 0) s[i] = 0;
        else s[i] = s[i - 1] + mp[vec[i]];
    }

    int ans = 0;
    for(int i = 0; i < nn - 1; i ++){
        int l = i + 1; int r = nn + nn - 1;
        while(l < r){
            int mid = (l + r) >> 1;
            if(s[mid] - s[i] >= c) r = mid;
            else l = mid + 1;
        }
       // cout << (s[l] - s[i]) << ' ' << vec[i + 1] - 1 - vec[i] + 1 << '\n';
        ans += (s[l] - s[i]) * (vec[i + 1] - 1 - vec[i] + 1);
    }

    cout << ans << '\n';
}

signed main(){
    std::ios::sync_with_stdio(false);
    int T = 1; //cin >> T;
    while(T--){
        solve();
    }
}

E - Hit and Away

对于每一个危险点,输出从一个安全点经过他到达另一个安全点的最小距离
这种跨着的,类似树的直径,随便四个更新都可以

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f

#define int long long

const int N = 200010;
vector<int> G[N];
int vis[N];
int d1[N], p1[N], d2[N], p2[N];

void solve(){
    int n, m; cin >> n >> m;
    while (m --)
    {
        int u, v; cin >> u >> v;
        G[u].pb(v); G[v].pb(u);
    }
    string s; cin >> s; s = "a" + s;

    queue<int> q;
    for(int i = 1; i <= n; i ++){
        d1[i] = INF; p1[i] = -1;
        d2[i] = INF; p2[i] = -1;
    }
    for(int i = 1; i <= n; i ++){
        if(s[i] == 'S'){
            d1[i] = 0; p1[i] = i;
            q.push(i);
        }
    }

    while(!q.empty()){
        int u = q.front(); q.pop();
        for(auto v:G[u]){
            if(d1[v] > d1[u] + 1 && p1[v] != p1[u]){
                d2[v] = d1[v];
                p2[v] = p1[v];
                d1[v] = d1[u] + 1;
                p1[v] = p1[u];
                q.push(v);
            }
             if(d2[v] > d1[u] + 1 && p1[v] != p1[u]){
                d2[v] = d1[u] + 1;
                p2[v] = p1[u];
                q.push(v);
            }
            if(d1[v] > d2[u] + 1 && p1[v] != p2[u]){
                d2[v] = d1[v];
                p2[v] = p1[v];
                d1[v] = d2[u] + 1;
                p1[v] = p2[u];
                q.push(v);
            }
            if(d2[v] > d2[u] + 1 && p1[v] != p2[u]){
                d2[v] = d2[u] + 1;
                p2[v] = p2[u];
                q.push(v);
            }
        }
    }


    for(int i = 1; i <= n; i ++){
     //   cout << d1[i] << ' ' << p1[i] << ' ' << d2[i] << ' ' << p2[i] << '\n';
        if(s[i] == 'D'){
            cout << d1[i] + d2[i] << '\n';
        }
    }
}

signed main(){
    std::ios::sync_with_stdio(false);
    int T = 1; //cin >> T;
    while(T--){
        solve();
    }
}

F - Shortest Path Query

三行,所以不可能往回走
分治,用线段树每次单点修改

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f

#define int long long


const int N = 200010;
char a[4][N];

struct Tree{
    int l, r;
    int d[4][4];
}tr[4*N];

void emp(Tree& u){
     for(int i = 1; i <= 3; i ++)
            for(int j = 1; j <= 3; j ++) u.d[i][j] = INF;
}
void emp(int u){
    emp(tr[u]);
}
void pushup(Tree& u, Tree & l, Tree & r){ 
     emp(u);
    u.l = l.l; u.r = r.r;
    for(int i = 1; i <= 3; i ++){
        for(int j = 1; j <= 3; j ++){
            for(int k = 1; k <= 3; k ++){
                if(a[k][l.r] == '.'){
                     u.d[i][j] = min(u.d[i][j], l.d[i][k] + 1 + r.d[k][j]);
                }
            }
        }
    }
}
void pushup(int u){
    pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void chg(int u){
    emp(u);
 for(int i = 1; i <= 3; i ++){
            int j = i;
            while(j >= 1 && a[j][tr[u].l] == '.'){
                tr[u].d[i][j] = abs(i - j);
                j --;
            } 
            j = i;
            while(j <= 3 && a[j][tr[u].l] == '.') {
                tr[u].d[i][j] = abs(i - j);
                j ++;
            }
        }
}

void bui(int u, int l, int r){
    emp(u);
    tr[u].l = l; tr[u].r = r;

    if(l == r){
        chg(u);
        return ;
    }
    int mid = (l + r) >> 1;
    bui(u*2, l, mid);
    bui(u*2 + 1, mid + 1, r);
    pushup(u);
}

void modify(int u, int x, int y){
    if(tr[u].l == tr[u].r && tr[u].l == y){ 
        chg(u);
        return ;
    }
    int mid = (tr[u].l + tr[u].r) >> 1;
    if(y <= mid) modify(u*2, x, y);
    else modify(u * 2 + 1, x, y);
    pushup(u);
}

void solve(){
    int n; cin >> n;
    for(int i = 1; i <= 3; i ++){
        string s; cin >> s;
        for(int j = 1; j <= n; j ++) a[i][j] = s[j - 1];
    }
   
    bui(1, 1, n);
    
    int q; cin >> q;
    while(q --){
        int x, y; cin >> x >> y;
        if(a[x][y] == '.')
        a[x][y] = '#';
        else a[x][y] = '.';

        modify(1, x, y);
        
        if(tr[1].d[1][3] > INF / 2) cout << -1 << '\n';
        else cout << tr[1].d[1][3] << '\n';
    }

}

signed main(){
    std::ios::sync_with_stdio(false);
    int T = 1;// cin >> T;
    while(T--){
        solve();
    }
}
posted @ 2025-12-08 00:38  arin876  阅读(6)  评论(0)    收藏  举报