模拟赛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\n",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\n",a2,a1); return 0; }