bzoj5017: [Snoi2017] Bomb

Believe me, this question is (tarjan shrink point + topological order dp + line segment merge + line segment tree optimization mapping)

Yesterday, the boss of P told me that this question is very different from C, which made me dead. . I looked at the next sign and found that it was the thing above. . . (What are you doing, the big guys collectively bring the rhythm a)

Then my water method is to enumerate the left and right extensions of each bomb, and learn to make a random number sequence.

Then it's over.

 

#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[R[i]-1]);
            L[i]=min(L[i],L[L[i]-1]), R[i]=max(R[i],R[R[i]-1]);
        }
        while(R[i]<n&&maxR[i]>=a[R[i]+1].x)
        {
            bk=true;
            minL[i]=min(minL[i],minL[L[i]+1]), maxR[i]=max(maxR[i],maxR[R[i]+1]);
            L[i]=min(L[i],L[L[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\n",ans);
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324761511&siteId=291194637