自己想的一个思路,把每个炸弹引爆的其他炸弹拆成左右两个区间分别dp(不是那个On错解),因为可能出现左右跳的情况,所以要记忆化搜索。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std; //预定义/预处理
#define inf 2000000000000000005
#define rg register
#define int long long
#define ull unsigned long long
inline int read()
{
rg int x = 0;
rg int flag = 1;
rg char ch = getchar();
while(ch < '0' or ch > '9')
{
if(ch == '-')
flag = -1;
ch = getchar();
}
while(ch >= '0' and ch <= '9')
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * flag;
}
inline void write(int x,char end='\n')
{
if(x==0)
{
putchar('0');
putchar(end);
return;
}
char F[205];
rg int tmp=x>0?x:-x ;
if(x<0)putchar('-') ;
int cnt=0 ;
while(tmp>0)
{
F[cnt++]=tmp%10+'0';
tmp/=10;
}
while(cnt>0) putchar(F[--cnt]);
putchar(end);
return;
}
inline int ksm(int di,int mi,int mod)
{
int an=1;
while(mi)
{
if(mi&1)
an=an*di%mod;
mi>>=1;
di=di*di%mod;
}
return an;
}
inline int mul(int di,int mi,int mod)
{
int an=0;
int f=(mi<0?-1:1);
f*=(di<0?-1:1);
mi=abs(mi);
di=abs(di);
while(mi)
{
if(mi&1)
an=(an+di)%mod;
mi>>=1;
di=(di+di)%mod;
}
return an*f;
}
#define ma 500005
map<int,int> vis;
int book[ma<<4];
int cnt;
int find(int i)
{
int l=1,r=cnt;
while(l<=r)
{
int mid=(l+r)>>1;
if(book[mid]==i) return mid;
if(book[mid]>i) r=mid-1;
else l=mid+1;
}
return -1;
}
bool lisan(int x,int y)
{
return x<y;
}
inline void ins(int x)
{
if(!vis[x]) vis[x]=1,book[++cnt]=x;
}
struct bong
{
int l,r,x,id;
bong(){}
bong(int ll,int rr,int xx,int iid)
{
l=ll;
r=rr;
x=xx;
id=iid;
}
}in[ma];
inline bool cmp(bong x,bong y)
{
return x.x<y.x;
}
const int deta=1e18+1;
const int mo=1e9+7;
const int de=(ma<<4)+(ma<<2);
//线段树
int root;
int ls[de],rs[de],ll[de],rr[de],tot,idl[de],idr[de],s[de];
inline void New(int &i)
{
i=++tot;
ll[i]=inf;
rr[i]=-inf;
return;
}
inline void push_up(int i)
{
ll[i]=min(ll[ls[i]],ll[rs[i]]);
rr[i]=max(rr[ls[i]],rr[rs[i]]);
idl[i]=(ll[i]==ll[ls[i]]? idl[ls[i]]:idl[rs[i]]);
idr[i]=(rr[i]==rr[ls[i]]? idr[ls[i]]:idr[rs[i]]);
if(ll[ls[i]]==ll[rs[i]]) idl[i]=min(idl[ls[i]],idl[rs[i]]);
if(rr[ls[i]]==rr[rs[i]]) idr[i]=max(idr[ls[i]],idr[rs[i]]);
s[i]=(s[ls[i]]+s[rs[i]]);
return;
}
void add(int &i,int l,int r,int pos,bong v)
{
if(l>r) return;
if(!i) New(i);
if(l==r)
{
idl[i]=idr[i]=v.id;
ll[i]=v.l;
rr[i]=v.r;
s[i]=1;
return;
}
int mid=(l+r)>>1;
if(pos<=mid) add(ls[i],l,mid,pos,v);
else add(rs[i],mid+1,r,pos,v);
push_up(i);
return;
}
int suml(int i,int l,int r,int L,int R)
{
if(L>R) return 0;
if(!i) return 0;
if(L<=l&&r<=R) return idl[i];
int ans=0,mid=(l+r)>>1;
if(L<=mid) ans=suml(ls[i],l,mid,L,R);
if(mid+1<=R)
{
int an=suml(rs[i],mid+1,r,L,R);
if(in[an].l<in[ans].l||(in[an].l==in[ans].l&&an<ans)) ans=an;
}
return ans;
}
int sumr(int i,int l,int r,int L,int R)
{
if(L>R) return 0;
if(!i) return 0;
if(L<=l&&r<=R) return idr[i];
int ans=0,mid=(l+r)>>1;
if(L<=mid) ans=sumr(ls[i],l,mid,L,R);
if(mid+1<=R)
{
int an=sumr(rs[i],mid+1,r,L,R);
if(in[an].r>=in[ans].r||(in[an].r==in[ans].r&&an>ans)) ans=an;
}
return ans;
}
int sum(int i,int l,int r,int L,int R)
{
if(L>R) return 0;
if(!i) return 0;
if(L<=l&&r<=R) return s[i];
int ans=0,mid=(l+r)>>1;
if(L<=mid) ans+=sum(ls[i],l,mid,L,R);
if(mid+1<=R) ans+=sum(rs[i],mid+1,r,L,R);
return ans;
}
int dpl[ma],dpr[ma];
int DPL(int now)
{
if(dpl[now]!=-1) return dpl[now];
int better=suml(root,1,cnt,in[now].l,in[now].r);
if(better>now)
{
dpl[better]=DPL(better);
return dpl[now]=dpl[better]-(better-now);
}
if(better==now)
return dpl[now]=sum(root,1,cnt,in[now].l,in[now].x-1);
if(dpl[better]==-1)
{
cout<<"AHHHHHH\n";
exit(0);
}
return dpl[now]=dpl[better]+(now-better);
}
int DPR(int now)
{
if(dpr[now]!=-1) return dpr[now];
int better=sumr(root,1,cnt,in[now].l,in[now].r);
if(better<now)
{
dpr[better]=DPR(better);
return dpr[now]=dpr[better]-(now-better);
}
if(better==now)
return dpr[now]=sum(root,1,cnt,in[now].x+1,in[now].r);
if(dpr[better]==-1)
{
cout<<"AHHHHHH\n";
exit(0);
}
return dpr[now]=dpr[better]+(better-now);
}
signed main()
{
memset(dpl,-1,sizeof(dpl));
memset(dpr,-1,sizeof(dpr));
int n=read();
in[0]=bong(inf,-inf,0,0);
ll[0]=inf;
rr[0]=-inf;
int r,ans=0;
for(int i=1;i<=n;i++)
{
in[i].x=read();
r=read();
in[i].l=in[i].x-r;
in[i].r=in[i].x+r;
ins(in[i].x);
ins(in[i].l);
ins(in[i].r);
}
sort(book+1,book+cnt+1,lisan);
sort(in+1,in+n+1,cmp);
for(int i=1;i<=n;i++)
{
in[i].x=find(in[i].x);
in[i].l=find(in[i].l);
in[i].r=find(in[i].r);
in[i].id=i;
add(root,1,cnt,in[i].x,in[i]);
}
for(int i=1;i<=n;i++)
if(dpl[i]==-1) dpl[i]=DPL(i);
for(int i=n;i>=1;i--)
if(dpr[i]==-1) dpr[i]=DPR(i);
for(int i=1;i<=n;i++) ans=(ans+(dpl[i]+dpr[i]+1)%mo*i%mo)%mo;
write(ans);
}
/*
4
1 1
5 1
6 5
15 15
*/
求错。。。hack数据也行(尽量小一点) 谢谢大佬们,感激不尽