正经求助贴
查看原帖
正经求助贴
40629
zzw4257楼主2020/8/14 11:55

这是正经的求助贴,他们叫我再发一次

RT,看了讨论里8686烦人分的几个人的错,我都没犯

实现特殊的一点是用了topsort,vector比较多...

#include<bits/stdc++.h>
#define N 6000001
#define ls(a) *son[a]
#define rs(a) son[a][1]
#define pb push_back
using namespace std;
typedef long long ll;
#define GG if(++ip==ie)if(fread(ip=ibuf,1,LL,stdin))
const int LL=1<<19;
char ibuf[LL],*ie=ibuf+LL,*ip=ie-1;
inline char nc(void){GG;return *ip;}
#define getchar nc
inline ll read(void){
    char opt;ll flag=1,res=0;
    while((opt=getchar())<'0'||opt>'9')if(opt=='-')flag=-1;
    while(opt>='0'&&opt<='9'){res=(res<<3)+(res<<1)+opt-'0';opt=getchar();}
    return res*flag;
}
struct Node{int l,r;}p[N<<2];
int rt,n,tot,sign,dfn[N],low[N],st[N],top,q[N<<1],ans,belong[N],SCC,mi[N],mx[N],son[N<<2][2],rd[N];
ll X[N],R[N]; 
vector<int>g[N],G[N];
inline void Build(int&pos,int l,int r){
    if(l==r)return void(p[pos=l]={l,l});
    if(!pos)p[pos=++tot]={l,r};int mid=(l+r)>>1;
    Build(ls(pos),l,mid),Build(rs(pos),mid+1,r);
    return g[pos].pb(ls(pos)),g[pos].pb(rs(pos));
}
inline void Add(int pos,int l,int r,int x,int ql,int qr){//入树 
    if(ql>qr)return ;
    if(ql<=l&&r<=qr)return void(g[x].pb(pos));
    int mid=(l+r)>>1;
    if(ql<=mid)Add(ls(pos),l,mid,x,ql,qr);
    if(qr>mid)Add(rs(pos),mid+1,r,x,ql,qr);
}
inline void Tarjan(int x){
    int t;dfn[st[++top]=x]=low[x]=++sign;
    for(int y:g[x]){
        if(!dfn[y])Tarjan(y),low[x]=min(low[x],low[y]);
        else if(!belong[y])low[x]=min(low[x],dfn[y]);
    }
    if(dfn[x]==low[x]){
        mi[++SCC]=n;
        do{belong[t=st[top--]]=SCC;mi[SCC]=min(mi[SCC],p[t].l),mx[SCC]=max(mx[SCC],p[t].r);}while(st[top+1]^x);
    }
}
signed main(void){
    int i,x,l=0,r=0;tot=n=read();Build(rt=0,1,n);
    for(i=1;i<=n;++i)X[i]=read(),R[i]=read();sort(X+1,X+n+1);
    for(i=1;i<=n;++i)Add(rt,1,n,i,lower_bound(X+1,X+n+1,X[i]-R[i])-X,i-1),Add(rt,1,n,i,i+1,upper_bound(X+1,X+n+1,X[i]+R[i])-X-1);
    Tarjan(n+1);
    for(x=1;x<=tot;++x)for(int y:g[x])if(belong[x]^belong[y])G[belong[x]].pb(belong[y]);
    for(x=1;x<=SCC;++x)G[x].resize(unique(G[x].begin(),G[x].end())-G[x].begin());
    for(x=1;x<=tot;++x)for(int y:G[x])++rd[y];
    for(x=1;x<=tot;++x)if(!rd[x])q[++r]=x;
    while(l<r){x=q[++l];for(int y:G[x]){mi[x]=min(mi[x],mi[y]),mx[x]=max(mx[x],mx[y]);if(!(--rd[y]))q[++r]=y;}}
    for(i=1;i<=n;++i)ans=(ans+1ll*i*(mx[belong[i]]-mi[belong[i]]+1ll))%1000000007;
    printf("%d\n",ans);
    return 0;
}
2020/8/14 11:55
加载中...