Wa on #8 求助
查看原帖
Wa on #8 求助
41476
gyh20楼主2020/8/12 17:23

思路就是线段树优化建图,最后记忆化搜索一遍得到答案,但 WA 了第 8 个点,不是数组问题,求助。

#include<bits/stdc++.h>
#define re register
#define M 1000000007
using namespace std;
inline long long read(){
	re long long t=0;re char v=getchar();
	while(v<'0')v=getchar();
	while(v>='0')t=(t<<3)+(t<<1)+v-48,v=getchar();
	return t;
}
int n,head[4000002],cnt,L[4000002],R[4000002],ll[4000002],rr[4000002],dfn[4000002],low[4000002],stk[4000002],ist[4000002],tp,tim,scc,tot,bl[4000002],vis[4000002],pos[4000002];
long long p[4000002],rrr[4000002];
struct edge{int to,next;}e[12000002];
inline void add(re int x,re int y){
	e[++cnt]=(edge){y,head[x]};
	head[x]=cnt;
}
inline int build(re int p,re int l,re int r){
	if(l==r)return pos[p]=l;
	re int mid=l+r>>1;
	L[++tot]=1e9;pos[p]=tot;
	add(pos[p],build(p<<1,l,mid)),add(pos[p],build(p<<1|1,mid+1,r));
	return pos[p];
}
inline void add(re int p,re int l,re int r,re int x,re int y,re int z){
	if(y<x)return;
	if(l>=x&&r<=y){
		add(z,pos[p]);
		return;
	}
	re int mid=l+r>>1;
	if(x<=mid)add(p<<1,l,mid,x,y,z);
	if(y>mid)add(p<<1|1,mid+1,r,x,y,z);
}
inline void tarjan(re int x){
	dfn[x]=low[x]=++tim,stk[++tp]=x,ist[x]=1;
	for(re int i=head[x];i;i=e[i].next)
		if(!dfn[e[i].to])tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
		else if(ist[e[i].to])low[x]=min(low[x],dfn[e[i].to]);
	if(low[x]==dfn[x]){
		re int p;ll[++scc]=1e9;
		do{
			ll[scc]=min(ll[scc],L[stk[tp]]);
			rr[scc]=max(rr[scc],R[stk[tp]]);
			ist[stk[tp]]=0,bl[stk[tp]]=scc;
		}while(stk[tp--]^x);
	}
}
vector<int>g[4000002];
inline void dfs(re int x){
	if(vis[x])return;
	vis[x]=1;
	for(re int i=0;i<g[x].size();++i)dfs(g[x][i]),ll[x]=min(ll[x],ll[g[x][i]]),rr[x]=max(rr[x],rr[g[x][i]]);
}
long long ans;
signed main(){
	n=read();
	for(re int i=1;i<=n;++i)p[i]=read(),rrr[i]=read(),L[i]=R[i]=i;tot=n;
	build(1,1,n);
	for(re int i=1;i<=n;++i){
		re int l=lower_bound(p+1,p+n+1,p[i]-rrr[i])-p,r=lower_bound(p+1,p+n+1,p[i]+rrr[i]+1)-p-1;
		if(l^i)add(1,1,n,l,i-1,i);
		if(r^i)add(1,1,n,i+1,r,i);
	}
	for(re int i=1;i<=tot;++i)if(!dfn[i])tarjan(i);
	for(re int i=1;i<=tot;++i)
		for(re int j=head[i];j;j=e[j].next)
			if(bl[i]^bl[e[j].to])g[bl[i]].push_back(bl[e[j].to]);
	for(re int i=1;i<=scc;++i)if(!vis[i])dfs(i);
	for(re int i=1;i<=n;++i)ans+=1ll*i*(rr[bl[i]]-ll[bl[i]]+1)%M,ans%=M;
	printf("%lld",ans);
}
2020/8/12 17:23
加载中...