AtCoder Beginner Contest 428

D - 183184

非常好的推式子
被at卡sqrt了

#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

using i128 = __int128;
using ull = unsigned long long;

int pp[20];
int qp(int a, int b){
    return pp[b];
}

int get(int x){
    int len = 0;
    while(x){
        len ++; x /= 10;
    }
    return len;
}
ll Sqrt1(ull x){//开根下取整
  ll l = 0, r = 1e10;
  while(l < r){
    ll mid = (l + r) >> 1;
    (i128)mid * mid >= x ? r = mid : l = mid + 1;
  }
  return l;
}

ll Sqrt2(ull x){//开根上取整
  ll l = 0, r = 1e10;
  while(l < r){
    ll mid = (l + r + 1) >> 1;
    (i128)mid * mid <= x ? l = mid : r = mid - 1;
  }
  return l;
}
void solve(){

    int c, d; cin >> c >> d;

    int ans = 0;
    for(int len = get(c + 1); len <= get(c + d); len ++ ){
        int r = min(d, qp(10, len) - 1 - c) + c * (qp(10, len) + 1);
        int l = max(1ll, qp(10, len - 1) - c) + c * (qp(10, len) + 1);

        r = Sqrt2(r);//r = floor(sqrt(r));
        l = Sqrt1(l);//l = ceil(sqrt(l));
        ans += r - l + 1;
       // ans += floor(sqrt(r)) - ceil(sqrt(l)) + 1;
    }

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

signed main(){
    std::ios::sync_with_stdio(false);

    pp[0] = 1;
    for(int i = 1; i <= 18; i ++) pp[i] = pp[i - 1] * 10;
    int T = 1; cin >> T;
    while(T--){
        solve();
    } 
}

E - Farthest Vertex

简单扯直径题

#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 = 500010;
vector<int> G[N];
int dep[N]; int mx = 0;

int pre[N];
bool vis[N];
int ans[N];

void dfs1(int u, int fa){
    dep[u] = dep[fa] + 1;
    if(dep[u] > dep[mx] ||(dep[u] == dep[mx] && u > mx)){
        mx = u;
    }
    for(auto v:G[u]){
        if(v == fa) continue;
        dfs1(v,u);
    }
}
void dfs2(int u, int fa){
    pre[u] = fa;
    dep[u] = dep[fa] + 1;
    if(dep[u] > dep[mx]||(dep[u] == dep[mx] && u > mx)){
        mx = u;
    }
    for(auto v:G[u]){
        if(v == fa) continue;
        dfs2(v, u);
    }
}

void dfs3(int u, int fa, int x){
    ans[u] = x;

    for(auto v:G[u]){
        if(v == fa) continue;
        if(vis[v]) continue;
        dfs3(v, u, x);
    }
}

void solve(){
    int n; cin >> n;
    for(int i = 1; i <= n - 1; i ++){
        int u, v; cin >> u >> v; G[u].pb(v); G[v].pb(u);
    }

    dfs1(1, 0);
    int st = mx; mx = 0; 
    dfs2(st, 0);
    int ed = mx;

    vector<int> vec;
    int tmp = ed; while(tmp) {
        vis[tmp] = 1;
        vec.pb(tmp); tmp = pre[tmp];
    }
        if(ed > st) reverse(vec.begin(), vec.end());

    for(int i = 0; i < vec.size(); i ++){
        int x = (i > (int)vec.size() - i - 1)? vec[0] : vec.back();
        dfs3(vec[i], 0, x);
    }

    for(int i = 1; i <= n; i ++){
        cout << ans[i] << '\n';
    }

}

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

F - Pyramid Alignment

发现x+1/2被一个区间i包含,必然被i+1包含,这样包含他的区间就是一个[i,n]的后缀,二分
线段树存上次左端还是右端对齐,以及对齐位置

#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;
int n;
int w[N];
struct Tree{
    int l, r;
    int k, lst;
    int ka, lsta;
}tr[4*N];

void pushup(Tree& u, Tree& l, Tree& r){
    if(l.k == r.k && l.lst == r.lst){
        u.k = l.k;
        u.lst = l.lst;
    }else {
        u.k = -1;
        u.lst = -1;
    }
}
void pushup(int u){
    pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void pushdown(Tree& u, Tree& l, Tree & r){
    if(u.ka != -1){
        l.k = u.k;
        l.lst = u.lst;
        l.ka = u.ka;
        l.lsta = u.lsta;

        r.k = u.k;
        r.lst = u.lst;
        r.ka = u.ka;
        r.lst = u.lst;

        u.ka = -1;
        u.lst = -1;
    }
}
void pushdown(int u){
    pushdown(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void bui(int u, int l, int r){
    tr[u] = {l, r, 0, 0, -1, -1};
    if(l == r){
        return ;
    }
    int mid = (tr[u].l + tr[u].r) >> 1;
    bui(u*2, l, mid);
    bui(u*2 + 1, mid + 1, r);
    pushup(u);
}

pii query(int u, int x){
    if(tr[u].l == x && tr[u].r == x){
        return {tr[u].k, tr[u].lst};
    }
    int mid = (tr[u].l + tr[u].r) >> 1;
    pushdown(u);
    if(x <= mid) return query(u << 1, x);
    else return query(u << 1 | 1, x);
}
void modify(int u, int x, int y, int k, int lst){
    if(x <= tr[u].l && tr[u].r <= y){
        tr[u].k = k; tr[u].lst = lst;
        tr[u].ka = k; tr[u].lsta = lst;
        return ;
    }

    pushdown(u);////
    int mid = (tr[u].l + tr[u].r) >> 1;
    if(x <= mid) modify(u << 1, x, y, k, lst);
    if(y >= mid + 1) modify(u << 1 | 1, x, y, k, lst);
    pushup(u);
}

bool ck(int mid, int x){
                auto [k, lst] = query(1, mid);
                int l, r;
                if(!k){
                    l = lst; r = lst + w[mid];
                }else {
                    l = lst - w[mid]; r = lst;
                }
                return (x >= l) && (x < r);
}



void solve(){
    cin >> n; 
    for(int i = 1; i <= n; i ++) cin >> w[i];

    bui(1, 1, n);
    // for(int i = 1; i <= n; i ++){
    //     cout << tr[i].l << ' ' << tr[i].r << '\n';
    // }
    int q; cin >> q;
    while(q --){
        int op, v, x; cin >> op;
        if(op == 1){
            cin >> v;
            auto [k,lst] = query(1, v);//上一次对齐左/右端点
            if(k) lst = lst - w[v];
            modify(1, 1, v, 0, lst);
        }else if(op == 2){
            cin >> v;
            auto [k,lst] = query(1, v);//上一次对齐左/右端点
            if(!k) lst = lst + w[v];
            modify(1, 1, v, 1, lst);
        }
        else {
            cin >> x;
            int l = 1; int r = n;
            while(l < r){
                int mid = (l + r) >> 1;
                if(ck(mid, x)) r = mid;
                else l = mid + 1;
            }
            if(ck(l, x)){
                cout << n - l + 1 << '\n';
            }else cout << 0 << '\n';
        }
    }
}

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