然而这只是 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;
}