相信我这题就是(tarjan缩点+拓扑序dp+线段合并+线段树优化建图)
昨天P老大跟我说这题跟C很不一样虚死我了。。看了下路牌发现就是上面那玩意。。。(搞什么啊大佬集体带节奏a)
那么我的水法就是枚举每个炸弹左右延伸咯,学习噶爷瞎搞个随机数列
然后完了。
upd:被rose_max D飞惹...因为数据太水...code有点小错(现在改回来了)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL mod=1e9+7; struct node { LL x,r; }a[510000]; LL L[510000],R[510000],minL[510000],maxR[510000]; int n;LL ans; void extend(LL i) { bool bk=true; while(bk==true) { bk=false; while(L[i]>1&&minL[i]<=a[L[i]-1].x) { bk=true; minL[i]=min(minL[i],minL[L[i]-1]), maxR[i]=max(maxR[i],maxR[L[i]-1]); R[i]=max(R[i],R[L[i]-1]), L[i]=min(L[i],L[L[i]-1]); } while(R[i]<n&&maxR[i]>=a[R[i]+1].x) { bk=true; minL[i]=min(minL[i],minL[R[i]+1]), maxR[i]=max(maxR[i],maxR[R[i]+1]); L[i]=min(L[i],L[R[i]+1]), R[i]=max(R[i],R[R[i]+1]); } } ans=(ans+ (i*(LL(R[i]-L[i]+1))%mod ) )%mod; } int rd[510000]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i].x,&a[i].r); ans=0; for(int i=1;i<=n;i++) L[i]=R[i]=i,minL[i]=a[i].x-a[i].r,maxR[i]=a[i].x+a[i].r; for(int i=1;i<=n;i++)rd[i]=i; random_shuffle(rd+1,rd+n+1); for(int i=1;i<=n;i++)extend( (LL(rd[i])) ); printf("%lld ",ans); return 0; }