84pts求调
查看原帖
84pts求调
324412
Filberte楼主2024/7/27 10:26

如题,应该不是像讨论区一样tarjan没有遍历所有线段树节点这一问题。WA on #1 #2

#include <bits/stdc++.h>
#define ll long long 
using namespace std;
bool _bg;
const int N = 5e5 + 100;
const int maxn = 2e6 + 100;
int n, nods;
struct Bomb{
    ll x, r;
    int mn, mx;
}a[N];
ll lsh[N];
vector<int> g[maxn];
void add_edge(int u, int v){if(u != v) g[u].push_back(v);}
int idt[N], fid[maxn];
void build(int u, int l, int r){
    nods++;
    if(l == r){
        idt[l] = u;
        fid[u] = l;
        return ;
    }
    int mid = (l + r) >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    add_edge(u, u << 1);
    add_edge(u, u << 1 | 1);
}
void upd(int u, int l, int r, int L, int R, int idx){
    if(l > r || L > R) return ;
    if(L <= l && r <= R){
        add_edge(idx, u);
        return ;
    }
    int mid = (l + r) >> 1;
    if(L <= mid) upd(u << 1, l, mid, L, R, idx);
    if(R > mid) upd(u << 1 | 1, mid + 1, r, L, R, idx);
}

int dfn[maxn], low[maxn], clk, st[maxn], tp;
bool inst[maxn];
int cs;int col[maxn];
int lft[maxn], rit[maxn];
void tarjan(int u){
    dfn[u] = low[u] = ++clk;
    st[++tp] = u;inst[u] = 1;
    for(int v : g[u]){
        if(!dfn[v]){
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(inst[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){
        ++cs;
        for(int x = 0;x != u;--tp){
            x = st[tp];int idx = fid[x];
            if(idx){
                lft[cs] = min(lft[cs], a[idx].mn);
                rit[cs] = max(rit[cs], a[idx].mx);
            }
            inst[x] = 0;
            col[x] = cs;
        }
    }
}
int sum[maxn];
vector<int> e[maxn];
vector<int> eds[maxn];
bool vis[maxn];
void dfs(int u){
    vis[u] = 1;
    for(int v : e[u]){
        if(!vis[u]) dfs(v);
        lft[u] = min(lft[u], lft[v]);
        rit[u] = max(rit[u], rit[v]);
    }
}
bool _ed;
int main(){
    //int t1 = clock();
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //cerr << 1.0 * (&_ed - &_bg) / 1024.0 / 1024.0 << "MB\n";
    cin >> n;
    fill(lft, lft + maxn, maxn);
    build(1, 1, n);
    for(int i = 1;i <= n;i++){
        cin >> a[i].x >> a[i].r;
        lsh[i] = a[i].x;
    }
    for(int i = 1;i <= n;i++){
        int pl = lower_bound(lsh + 1, lsh + 1 + n, max(a[1].x, a[i].x - a[i].r)) - lsh;
        int pr = upper_bound(lsh + 1, lsh + 1 + n, min(a[n].x, a[i].x + a[i].r)) - lsh - 1;
        a[i].mn = max(1, min(i, pl));
        a[i].mx = min(max(i, pr), n);
        upd(1, 1, n, pl, pr, idt[i]);
    }
    for(int i = 1;i <= nods;i++) if(!dfn[i]) tarjan(i);
    for(int u = 1;u <= nods;u++)
        for(int v : g[u]) eds[col[u]].push_back(col[v]);
    tp = 0;
    for(int u = 1;u <= cs;u++){
        for(int v : eds[u]){
            if(vis[v] || u == v) continue;
            e[u].push_back(v);
            vis[v] = 1;
            st[++tp] = v;
        }
        while(tp) vis[st[tp--]] = 0;
    }
    ll ret = 0, mod = 1e9 + 7;
    for(int j = 1;j <= n;j++){
        int i = idt[j];
        int c = col[i];
        if(!vis[c]) dfs(c);
        ret = (ret + 1ll * (rit[c] - lft[c] + 1) * j % mod) % mod;
    }
    cout << ret << endl;
    //int t2 = clock();
    //cerr << (t2 - t1) << "ms\n";
    return 0;
}       
2024/7/27 10:26
加载中...