线段树优化建图+tarjan缩点 84pts 求调
查看原帖
线段树优化建图+tarjan缩点 84pts 求调
1303297
Qiuliyang楼主2025/7/3 21:55

数组开大了就MLE,开小了就RE

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int n,m,to[500005],dfn[6500005],low[6500005],tot,sta[6500005],tp,scc[5000005],sz[5000005],cnt,minn[5000005],maxn[5000005],mod = 1e9 + 7;
bool in_s[6500005];
long long ans,x[500005],r[500005];
vector<int> map[6500005],G[5000005];
struct edge{
	int u,v;
}g[6500005];
int ls(int p)
{
	return p * 2;
}
int rs(int p)
{
	return p * 2 + 1;
}
void build(int pl,int pr,int p)
{
	if(pl == pr)
	{
		to[pl] = p;
		return;
	}
	map[p].push_back(ls(p));
	map[p].push_back(rs(p));
	g[++m] = {p,ls(p)};
	g[++m] = {p,rs(p)};
	int mid = (pl+pr)/2;
	build(pl,mid,ls(p));
	build(mid+1,pr,rs(p));
}
void updata(int l,int r,int pl,int pr,int p,int u)
{
	if(l <= pl && pr <= r)
	{
		map[u].push_back(p);
		g[++m] = {u,p};
		return;
	}
	int mid = (pl+pr)/2;
	if(l <= mid) updata(l,r,pl,mid,ls(p),u);
	if(mid+1 <= r) updata(l,r,mid+1,pr,rs(p),u);
}
void f(int u)
{
	dfn[u] = low[u] = ++tot;
	sta[++tp] = u;
	in_s[u] = true;
	for(int i = 0; i < map[u].size(); i++)
	{
		int v = map[u][i];
		if(!dfn[v])
		{
			f(v);
			low[u] = min(low[u],low[v]);
		}
		else if(in_s[v])
		{
			low[u] = min(low[u],dfn[v]);
		}
	}
	if(dfn[u] == low[u])
	{
		cnt++;
		do{
			sz[cnt]++;
			scc[sta[tp]] = cnt;
			in_s[sta[tp]] = false;
		} while(sta[tp--] != u);
	}
}
void dfs1(int u,int d)
{
	if(minn[u]) return;
	minn[u] = d;
	for(int i = 0; i < G[u].size(); i++)
	{
		int v = G[u][i];
		dfs1(v,d);
	}
}
void dfs2(int u,int d)
{
	if(maxn[u]) return;
	maxn[u] = d;
	for(int i = 0; i < G[u].size(); i++)
	{
		int v = G[u][i];
		dfs2(v,d);
	}
}
signed main()
{
	cin >> n;
	build(1,n,1);
	for(int i = 1; i <= n; i++)
	{
		cin >> x[i] >> r[i];
	}
	for(int i = 1; i <= n; i++)
	{
		long long a = x[i] - r[i],b = x[i] + r[i];
		int minl = lower_bound(x + 1,x + n + 1,a) - x,maxr = upper_bound(x + 1,x + n + 1,b) - x - 1;
		if(minl < i) updata(minl,i-1,1,n,1,to[i]);
		if(maxr > i) updata(i+1,maxr,1,n,1,to[i]);
	}
	for(int i = 1; i < 2*n; i++)
	{
		if(!dfn[i])
		{
			f(i);
		}
	}
	for(int i = 1; i <= m; i++)
	{
		int u = g[i].u,v = g[i].v;
		if(scc[u] != scc[v])
		{
			G[scc[v]].push_back(scc[u]);
		}
	}
	for(int i = 1; i <= n; i++)
	{
		dfs1(scc[to[i]],i); 
	}
	for(int i = n; i >= 1; i--)
	{
		dfs2(scc[to[i]],i);
	}
	for(int i = 1; i <= n; i++)
	{
		ans += 1ll * i * (maxn[scc[to[i]]] - minn[scc[to[i]]] + 1);
		ans %= mod; 
	}
	cout << ans << endl;
	return 0;
}
2025/7/3 21:55
加载中...