如题,应该不是像讨论区一样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;
}