zoukankan      html  css  js  c++  java
  • 模拟赛T2 线段树优化建图+tarjan+拓扑排序

    然而这只是 70pts 的部分分,考场上没想到满分怎么做(现在也不会)  

    code: 

    #include <cstdio> 
    #include <string>
    #include <stack>  
    #include <queue>    
    #include <cstring>
    #include <algorithm>  
    #define N 100009 
    #define lson ls[x] 
    #define rson rs[x]  
    #define inf 4500000   
    using namespace std; 
    void setIO(string s) {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
        freopen(out.c_str(),"w",stdout); 
    }     
    int scc;  
    int cnt;   
    int n;   
    int tot;   
    int edges;    
    int A[N*5];   
    int hd[N*5]; 
    int to[N*30];   
    int nex[N*30];   
    int ls[N*5]; 
    int rs[N*5];   
    int vis[N*5];   
    int dfn[N*5]; 
    int low[N*5];  
    int id[N*5];      
    int In[N*5];  
    int Ou[N*5];   
    int tag[N*5];   
    int X[N],L[N],R[N],con[N];
    int is[N*5];             
    stack<int>S;   
    queue<int>q;    
    vector<int>G[N*5];   
    int newnode() { 
        return ++tot; 
    }
    void add(int u,int v) {
        // printf("%d %d
    ",u,v);   
        nex[++edges]=hd[u]; 
        hd[u]=edges; 
        to[edges]=v;    
    }
    void update(int &x,int l,int r,int p) {
        if(l==r) {
            x=p;   
            return;  
        }
        if(!x) {
            x=newnode(); 
        }
        int mid=(l+r)>>1;  
        if(X[p]<=mid) {
            update(lson,l,mid,p); 
        } 
        else {
            update(rson,mid+1,r,p); 
        }
    }
    void build(int x) {
        if(lson) {
            add(x,lson); 
            build(lson); 
        }
        if(rson) {
            add(x,rson); 
            build(rson); 
        }
    }
    void Add(int x,int l,int r,int L,int R,int rt) {
        if(!x) {
            return; 
        }
        if(l>=L&&r<=R) {
            add(rt,x); 
            return; 
        }
        int mid=(l+r)>>1;   
        if(L<=mid) {
            Add(lson,l,mid,L,R,rt); 
        }
        if(R>mid) {
            Add(rson,mid+1,r,L,R,rt); 
        }
    }
    void tarjan(int u) {        
        vis[u]=1;   
        S.push(u);  
        low[u]=dfn[u]=++cnt;   
        for(int i=hd[u];i;i=nex[i]) {
            int v=to[i];   
            if(!vis[v]) {
                tarjan(v);   
                low[u]=min(low[u],low[v]); 
            }
            else if(vis[v]==1) {
                low[u]=min(low[u],dfn[v]);    
            }
        }
        if(low[u]==dfn[u]) {
            ++scc;  
            for(;;) {
                int x=S.top(); 
                S.pop(); 
                id[x]=scc;     
                vis[x]=-1;    
                if(x==u) {
                    break;  
                }
            }
        }
    }
    int main() {
        // setIO("broadcast"); 
        int i,j;  
        scanf("%d",&n); 
        tot=n;  
        int tp=0;  
        int root=0; 
        for(i=1;i<=n;++i) {
            scanf("%d%d",&X[i],&con[i]);    
            L[i]=X[i]-con[i]; 
            R[i]=X[i]+con[i];     
            A[++tp]=X[i];   
            A[++tp]=L[i]; 
            A[++tp]=R[i];        
        }      
        sort(A+1,A+1+tp); 
        for(i=1;i<=n;++i) {
            X[i]=lower_bound(A+1,A+1+tp,X[i])-A; 
            L[i]=lower_bound(A+1,A+1+tp,L[i])-A; 
            R[i]=lower_bound(A+1,A+1+tp,R[i])-A;  
        }      
        for(i=1;i<=n;++i) {
            update(root,1,inf,i);    
        }
        build(root);       
        for(i=1;i<=n;++i) {  
            Add(root,1,inf,L[i],R[i],i);   
        }   
        for(i=1;i<=n;++i) {
            if(!vis[i]) {
                tarjan(i);   
            }
        }                    
        for(i=1;i<=tot;++i) {
            for(j=hd[i];j;j=nex[j]) {
                int v=to[j];    
                if(!id[i]||!id[v]) {
                    continue;   
                }                          
                if(id[v]!=id[i]) {
                    ++In[id[v]];             
                    ++Ou[id[i]];  
                    G[id[i]].push_back(id[v]); 
                }
            }
        }
        for(i=1;i<=n;++i) {
            is[id[i]]=1;                
        }
        for(i=1;i<=scc;++i) {           
            if(!In[i]) {              
                q.push(i); 
            }
        }     
        while(!q.empty()) {    
            int u=q.front();                          
            q.pop();    
            for(int i=0;i<G[u].size();++i) {
                int v=G[u][i];      
                --In[v];   
                tag[v]|=(tag[u]|is[u]);    
                if(!In[v]) {            
                    q.push(v);   
                }
            }       
        }    
        int a1=0; 
        int a2=0; 
        for(i=1;i<=scc;++i) {
            if(is[i]) {    
                ++a1;          
            }
        }
        for(i=1;i<=scc;++i) {
            if(!tag[i]&&is[i]) {
                ++a2; 
            }
        }
        printf("%d %d
    ",a2,a1);                               
        return 0;
    }
    

      

  • 相关阅读:
    2018-8-10-win10-uwp-商业游戏-1.2.1
    2018-8-10-win10-uwp-商业游戏-1.2.1
    2019-3-1-获取-Nuget-版本号
    2019-3-1-获取-Nuget-版本号
    2019-9-24-dotnet-remoting-抛出异常
    2019-9-24-dotnet-remoting-抛出异常
    2018-2-13-C#-解析-sln-文件
    2018-2-13-C#-解析-sln-文件
    2018-10-19-jekyll-添加-Valine-评论
    2018-10-19-jekyll-添加-Valine-评论
  • 原文地址:https://www.cnblogs.com/guangheli/p/12075814.html
Copyright © 2011-2022 走看看