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 }

 

posted @ 2018-10-13 10:44  Ressed  阅读(169)  评论(0编辑  收藏  举报