bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)
直接建图边数太多,用线段树优化一下
然后缩点,记下来每个点里有多少个炸弹
然后按拓扑序反向dp一下就行了
1 #include<bits/stdc++.h> 2 #define pa pair<ll,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=5e5+10,maxp=maxn*4,maxl=maxn*30,P=1e9+7; 7 const ll inf=1e18+1; 8 9 inline ll rd(){ 10 ll x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 int N; 17 ll pos[maxn],r[maxn]; 18 int rg[maxn][2],id[maxn],ch[maxp][2],pct,root; 19 int eg[maxl][2],egh[maxp],ect; 20 int eg2[maxl][2],egh2[maxp],ect2,ine[maxp]; 21 int dfn[maxp],low[maxp],tot,stk[maxp],sh; 22 int bel[maxp],nct,hav[maxp],hh[maxp]; 23 int val[maxp],rk[maxp]; 24 bool instk[maxp],islef[maxp],to[maxp]; 25 queue<int> q; 26 27 inline void adeg(int a,int b){ 28 eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect; 29 } 30 inline void adeg2(int a,int b){ 31 ine[b]++; 32 eg2[++ect2][0]=b;eg2[ect2][1]=egh2[a];egh2[a]=ect2; 33 } 34 35 void build(int &p,int l,int r){ 36 p=++pct; 37 if(l==r) id[l]=p,islef[p]=1; 38 if(l<r){ 39 int m=l+r>>1; 40 build(ch[p][0],l,m); 41 build(ch[p][1],m+1,r); 42 adeg(p,ch[p][0]),adeg(p,ch[p][1]); 43 } 44 } 45 46 void conn(int p,int l,int r,int x,int y,int z){ 47 if(x>y) return; 48 if(x<=l&&r<=y){ 49 adeg(z,p); 50 }else{ 51 int m=l+r>>1; 52 if(x<=m) conn(ch[p][0],l,m,x,y,z); 53 if(y>=m+1) conn(ch[p][1],m+1,r,x,y,z); 54 } 55 } 56 57 void tarjan(int x){ 58 dfn[x]=low[x]=++tot; 59 stk[++sh]=x;instk[x]=1; 60 for(int i=egh[x];i;i=eg[i][1]){ 61 int b=eg[i][0]; 62 if(instk[b]) low[x]=min(low[x],dfn[b]); 63 else if(!dfn[b]){ 64 tarjan(b); 65 low[x]=min(low[x],low[b]); 66 } 67 } 68 if(dfn[x]==low[x]){ 69 ++nct; 70 while(sh){ 71 bel[stk[sh]]=nct; 72 hav[stk[sh]]=hh[nct],hh[nct]=stk[sh]; 73 val[nct]+=islef[stk[sh]]; 74 instk[stk[sh]]=0; 75 sh--; 76 if(stk[sh+1]==x) break; 77 } 78 } 79 } 80 81 int main(){ 82 //freopen(".in","r",stdin); 83 int i,j,k; 84 N=rd(); 85 for(i=1;i<=N;i++) pos[i]=rd(),r[i]=rd(); 86 for(i=1;i<=N;i++){ 87 rg[i][0]=lower_bound(pos+1,pos+N+1,pos[i]-r[i])-pos; 88 rg[i][1]=upper_bound(pos+1,pos+N+1,pos[i]+r[i])-pos-1; 89 // printf("%d %d %d\n",i,rg[i][0],rg[i][1]); 90 } 91 build(root,1,N); 92 for(i=1;i<=N;i++){ 93 conn(root,1,N,rg[i][0],i-1,id[i]); 94 conn(root,1,N,i+1,rg[i][1],id[i]); 95 } 96 for(i=1;i<=pct;i++){ 97 if(!dfn[i]) tarjan(i); 98 } 99 for(i=1;i<=nct;i++){ 100 for(j=hh[i];j;j=hav[j]){ 101 for(k=egh[j];k;k=eg[k][1]){ 102 int bb=bel[eg[k][0]];if(bb==i) continue; 103 if(!to[bb]) adeg2(i,bb),to[bb]=1; 104 } 105 } 106 107 for(j=hh[i];j;j=hav[j]){ 108 for(k=egh[j];k;k=eg[k][1]){ 109 int bb=bel[eg[k][0]]; 110 to[bb]=0; 111 } 112 } 113 } 114 int nn=0; 115 for(i=1;i<=nct;i++){ 116 if(!ine[i]) q.push(i); 117 } 118 while(!q.empty()){ 119 int p=q.front();q.pop(); 120 rk[++nn]=p; 121 for(i=egh2[p];i;i=eg2[i][1]){ 122 int b=eg2[i][0]; 123 if(--ine[b]==0) q.push(b); 124 } 125 126 } 127 for(i=nct;i;i--){ 128 int p=rk[i]; 129 for(j=egh2[p];j;j=eg2[j][1]){ 130 int b=eg2[j][0]; 131 val[p]+=val[b]; 132 } 133 } 134 ll ans=0; 135 for(i=1;i<=N;i++){ 136 ans=(ans+1ll*i*val[bel[id[i]]])%P; 137 } 138 printf("%lld\n",ans); 139 return 0; 140 }