- 数组已经开到 6×106,应该可以排除数组开小了
- 会爆int的地方已经开了long long,且试过
#define int long long,没有变化
- 跟着题解写的,写完后对照了一遍,似乎没有什么细节上的区别
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
#include<utility>
using namespace std;
typedef long long ll;
inline ll read(){
ll ret=0;
char ch=' ',c=getchar();
while(!('0'<=c&&c<='9')) ch=c,c=getchar();
while('0'<=c&&c<='9') ret=(ret<<1)+(ret<<3)+(c^48),c=getchar();
return ch=='-'?-ret:ret;
}
int n,tot=0;
const int N=6e6+10,M=1e7+10;
int np[N];
bool is_real[N];
ll pos[N],ran[N];
struct graph{
int to[M],nt[M],idx,h[N];
inline void add(int x,int y){
to[idx]=y;
nt[idx]=h[x];
h[x]=idx++;
}
graph(){
idx=0;
memset(h,-1,sizeof(h));
}
} ori,ano;
struct NODE{
int l,r;
} tr[N];
void build(int u,int l,int r){
tr[u]=(NODE){l,r};
tot=max(tot,u);
if(l==r){
np[l]=u;
is_real[u]=true;
return ;
}
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
ori.add(u,u<<1);
ori.add(u,u<<1|1);
}
void modify(int u,int l,int r,int fa){
if(l<=tr[u].l&&tr[u].r<=r){
ori.add(fa,u);
return ;
}
int mid=(tr[u].l+tr[u].r)>>1;
if(l<=mid) modify(u<<1,l,r,fa);
if(r>mid) modify(u<<1|1,l,r,fa);
}
int timestamp=0;
int dfn[N];
int low[N];
int stk[N];
int hh=0,tt=-1;
bool instk[N];
int scc_cnt=0;
int id[N],sz[N];
int zuo[N],you[N];
void tarjan(int u){
timestamp++;
dfn[u]=timestamp;
low[u]=timestamp;
stk[++tt]=u;
instk[u]=true;
for(int i=ori.h[u];i!=-1;i=ori.nt[i]){
int j=ori.to[i];
if(!dfn[j]){
tarjan(j);
low[u]=min(low[u],low[j]);
}
else if(instk[j]){
low[u]=min(low[u],dfn[j]);
}
}
if(dfn[u]==low[u]){
scc_cnt++;
zuo[scc_cnt]=0x3f3f3f3f;
int t;
do{
t=stk[tt--];
instk[t]=false;
id[t]=scc_cnt;
if(is_real[t]) sz[scc_cnt]++;
zuo[scc_cnt]=min(zuo[scc_cnt],tr[t].l);
you[scc_cnt]=max(you[scc_cnt],tr[t].r);
}while(t!=u);
}
}
bool v[N];
void dfs(int u){
v[u]=true;
for(int i=ano.h[u];i!=-1;i=ano.nt[i]){
int j=ano.to[i];
if(!v[j]) dfs(j);
zuo[u]=min(zuo[u],zuo[j]);
you[u]=max(you[u],you[j]);
}
}
vector<ll> vct;
int upb(ll x){
int l=1,r=n,mid;
while(l<r){
mid=(l+r)>>1;
if(vct[mid]>=x) r=mid;
else l=mid+1;
}
return l;
}
int lob(ll x){
int l=1,r=n,mid;
while(l<r){
mid=(l+r+1)>>1;
if(vct[mid]<=x) l=mid;
else r=mid-1;
}
return l;
}
int main(){
vct.push_back(0xc3c3c3c3c3c3c3c3);
n=read();
for(int i=1;i<=n;i++){
pos[i]=read(),ran[i]=read();
vct.push_back(pos[i]);
}
build(1,1,n);
for(int i=1;i<=n;i++){
int l=upb(pos[i]-ran[i]);
int r=lob(pos[i]+ran[i]);
modify(1,l,r,np[i]);
}
tarjan(1);
for(int u=1;u<=tot;u++){
for(int i=ori.h[u];i!=-1;i=ori.nt[i]){
int j=ori.to[i];
if(id[u]!=id[j]){
ano.add(id[u],id[j]);
}
}
}
for(int i=1;i<=scc_cnt;i++) dfs(i);
ll ans=0;
for(ll i=1;i<=n;i++){
ans+=i*(you[id[np[i]]]-zuo[id[np[i]]]+1);
}
printf("%lld",ans);
return 0;
}