zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",ans);
    139     return 0;
    140 }
  • 相关阅读:
    python-pytest使用
    PyCharm2021使用教程 --- 11、PyCharm必备插件
    PyCharm2021使用教程 --- 10、PyCharm中实用小技巧
    PyCharm2021使用教程 ---9、PyCharm中的搜索技巧(文件/函数/内容)
    PyCharm2021使用教程 --- 8、版本控制
    PyCharm2021使用教程 --- 7、如何使用DeBug调试程序
    PyCharm2021使用教程 --- 6、如何运行程序
    PyCharm2021使用教程 --- 5、PyCharm的基本配置
    PyCharm2021使用教程 --- 4、菜单栏详细介绍
    PyCharm2021使用教程 --- 3、使用pycharm创建项目
  • 原文地址:https://www.cnblogs.com/Ressed/p/9782146.html
Copyright © 2011-2022 走看看