萌新刚学优化建图84pts求助
查看原帖
萌新刚学优化建图84pts求助
716260
SegmentTree_楼主2024/6/17 20:06

TLE#11 WA#12

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lid (id << 1)
#define rid (id << 1 | 1)
const int N = 5e5+5;
const ll mod=1e9+7;
int n;
ll ax[N], ar[N];
int head[N << 2], nxt[N << 3], from[N << 3], to[N << 3], cccnnnttt;
void add(int u, int v){
	to[++cccnnnttt] = v;
	from[cccnnnttt] = u;
	nxt[cccnnnttt] = head[u];
	head[u] = cccnnnttt;
}
struct node{
	int l, r, id;
}tr[N << 2];
int rnk[N << 2];
void build(int id, int l, int r){
	//cout << l << ' ' << r << '\n';
	tr[id].l = l;
	tr[id].r = r;
	tr[id].id = 0;
	if (l == r){
		tr[id].id = l;
		rnk[l] = id;
		return;
	}
	int mid = (l + r) >> 1;
	build(lid, l, mid);
	build(rid, mid + 1, r);
	add(id, lid);
	add(id, rid);
}
void link(int id, int l, int r, int x){
	if (l <= tr[id].l && tr[id].r <= r){
		if (id != x) add(x, id);
		return;
	}
	int mid = (tr[id].l + tr[id].r) >> 1;
	if (l <= mid) link(lid, l, r, x);
	if (r > mid) link(rid, l, r, x);
}
int dfn[N << 2], low[N << 2], tot;
bool vis[N << 2];
stack<int> st;
int scc[N << 2], sccsum[N << 2], scctot;
int lest[N << 2], rest[N << 2];
int deg[N << 2];
void tarjan(int u){
	dfn[u] = low[u] = ++tot;
	vis[u] = 1;
	st.push(u);
	for (int i = head[u];i;i = nxt[i]){
		int v= to[i];
		if (!dfn[v]){
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (vis[v]){
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (low[u] == dfn[u]){
		++scctot;
		lest[scctot] = 0x3f3f3f3f;
		rest[scctot] = 0;
		while (1){
			int tp = st.top();
			st.pop();
			scc[tp] = scctot;
			if (tr[tp].id) ++sccsum[scctot];
			lest[scctot]  = min(lest[scctot],tr[tp].l);
			rest[scctot] = max(rest[scctot], tr[tp].r);
			vis[tp] = 0;
			if (tp == u) break;
		}
	}
}
int topo[N << 2];
void gettopo(){
	queue<int> q;
	for (int i = 1;i <= scctot;i++){
		if (!deg[i]) q.push(i);
	}
	while (q.size()){
		int hd = q.front();
		q.pop();
		for (int i = head[hd];i;i = nxt[i]){
			int v = to[i];
			lest[v] = min(lest[v], lest[hd]);
			rest[v] = max(rest[v], rest[hd]);
			if (!(--deg[v])) q.push(v);
		}
	}
}
signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n;
//	for (int i = 0;i <= 4 * n;i++) lest[i] = INT_MAX, rest[i] = INT_MIN;
	build(1, 1, n);
	for (int i = 1;i <= n;i++){
		cin >> ax[i] >> ar[i];
	}
	for (int i = 1;i <= n;i++){
		int l1 = lower_bound(ax + 1, ax + 1 + n, ax[i] - ar[i]) - ax;
		int r1 = upper_bound(ax + 1, ax + 1 + n, ax[i] + ar[i]) - ax - 1;
		if (l1 <= r1) link(1, l1, r1, rnk[i]);
	}
	tarjan(1);
	int tmp = cccnnnttt;
	for (int i = 1;i <= scctot;i++) head[i] = 0;
	cccnnnttt = 0;
	for (int i = 1;i <= tmp;i++){
		int u = scc[from[i]], v = scc[to[i]];
		if (u != v){
			add(v, u);
			++deg[u];
		}
	}
	gettopo();
	ll ans = 0;
	for (int i = 1;i <= n;i++){
		ans = ((ll)i * (ll)(rest[scc[rnk[i]]] - lest[scc[rnk[i]]] + 1)%mod+ans)%mod;
//		cout << lest[scc[rnk[i]]] << ' ' << rest[scc[rnk[i]]] << '\n';
	}
	cout << ans;
	return 0;
}
2024/6/17 20:06
加载中...