正经求助
查看原帖
正经求助
280635
SMTwy楼主2022/10/26 21:22

看的第二篇题解,线段树优化建图+tarjan缩点,WA1,2,本地拍了一个小时了。。。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls rt<<1
#define rs rt<<1|1
#define mid ((l+r)>>1)
const int mx=5e5+1000;
const int mod=1e9+7;
int n,ID,len,tot,cnt,head[mx<<3],dfn[mx<<3],low[mx<<3],L[mx<<3],R[mx<<3];
int dui[mx<<3],lef[mx<<3],righ[mx<<3],belong[mx<<3];
ll x[mx],r[mx];
bool vis[mx];
stack <int> sta;
vector <int> scc[mx<<3],G[mx<<3];
struct Node{
    int to,next;
}e[mx*30];
struct Tree{
    int id,l,r;
}t[mx<<2];
inline void Insert(int u,int v){
    e[++len].to=v;
    e[len].next=head[u];
    head[u]=len;
}
inline void Pushup(int rt){
    Insert(t[rt].id,t[ls].id);Insert(t[rt].id,t[rs].id);
}
void Build(int rt,int l,int r){
    t[rt].l=l;t[rt].r=r;
    if(l==r){
       dui[l]=rt;t[rt].id=l;return ;
    }
    Build(ls,l,mid);Build(rs,mid+1,r);
    t[rt].id=++ID;dui[ID]=rt;
    Pushup(rt);
}
void updata(int rt,int l,int r,int L,int R,int from){
    if(L<=l && R>=r){
        if(from==t[rt].id)return ;
        Insert(from,t[rt].id);return ;
    }
    if(L<=mid)updata(ls,l,mid,L,R,from);
    if(R>mid)updata(rs,mid+1,r,L,R,from);
}
void Tarjan(int u){
    dfn[u]=low[u]=++tot;sta.push(u);
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(!dfn[v]){
            Tarjan(v);low[u]=min(low[u],low[v]);
        }
        else low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        cnt++;int x=0;
        do{
            x=sta.top();sta.pop();
            scc[cnt].push_back(x);belong[x]=cnt;
            lef[cnt]=min(lef[cnt],t[dui[x]].l);
            righ[cnt]=max(righ[cnt],t[dui[x]].r);
        }while(x!=u);
    }
} 
void dfs(int u){
    for(auto v: G[u]){
        if(vis[v]){
            lef[u]=min(lef[v],lef[u]);
            righ[u]=max(righ[u],righ[v]);
            continue;
        }
        vis[v]=1;dfs(v);
        lef[u]=min(lef[v],lef[u]);
        righ[u]=max(righ[u],righ[v]);
    }
}
void MYH(){
    scanf("%d",&n);ID=n;
    for(int i=1;i<=n;++i){
        scanf("%lld%lld",&x[i],&r[i]);
    }
    Build(1,1,n);x[n+1]=1e18;
    memset(lef,0x3f,sizeof(lef));
    //for(int i=1;i<=n*3;++i)lef[i]=mx+10;
    for(int i=1;i<=n;++i){
        int pos1=lower_bound(x+1,x+i-1+1,x[i]-r[i])-x;
        int pos2=upper_bound(x+i+1,x+n+1,x[i]+r[i])-x-1;
        updata(1,1,n,pos1,pos2,i);L[i]=pos1;R[i]=pos2;
    }
    Tarjan(ID);
    for(int u=1;u<=ID;++u){
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(belong[u]==belong[v])continue;
            G[belong[u]].push_back(belong[v]);
        }
    }
    for(int i=1;i<=cnt;++i){
        if(!vis[i]){vis[i]=1;dfs(i);}
    }
    ll ans=0;
    for(int i=1;i<=n;++i){
        ans=(ans+1ll*(1ll*righ[belong[i]]-1ll*lef[belong[i]]+1)*i%mod)%mod;
    }
    printf("%lld\n",ans);
}
int main(){
    MYH();
    return 0;
}
2022/10/26 21:22
加载中...