第一次学扫描线,能过5个样例,为什么啊
查看原帖
第一次学扫描线,能过5个样例,为什么啊
774800
EX_BSGS楼主2024/3/24 20:19
#include <bits/stdc++.h>
#define int long long
using namespace std;
#define ls u<<1
#define rs u<<1|1

const int N = 200010;
int pre[N];
int nxt[N];
int st[N];
int a[N];
int X[N];
struct line{
	int x1,x2,y;
	int tag;
	bool operator<(line &t){return y<t.y;}
}L[N];
struct tree{
	int l,r;
	int cnt,len;
}tr[N*8];
void pushup(int u){
	int l = tr[u].l, r = tr[u].r;
	if(tr[u].cnt) tr[u].len = X[r+1] - X[l];//向右偏移
	else tr[u].len = tr[ls].len + tr[rs].len;
}
void build(int u,int l,int r){
	tr[u]={l,r,0,0};
	if(l==r) return;
	int mid = (l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
}
void modify(int u,int l,int r,int tag){
	if(l>tr[u].r||r<tr[u].l) return;
	if(l<=tr[u].l&&r>=tr[u].r){
		tr[u].cnt+=tag;
		pushup(u);
		return;
	}
	modify(ls,l,r,tag);
	modify(rs,l,r,tag);
	pushup(u);
}
map<int,int>mp;
signed main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1; i<=n; i++) {
		pre[i]=mp[a[i]]+1;
		mp[a[i]]=i;
	}
	mp.clear();
	for(int i=n; i>=1; i--) {
		if(mp[a[i]])nxt[i]=mp[a[i]]-1;
		else nxt[i]=n;
		mp[a[i]]=i;
	}
	for(int i=1;i<=n;i++){
		L[i]={pre[i],i+1,i,1};
		L[i+n]={pre[i],i+1,nxt[i]+1,-1};
		X[i]=pre[i],X[i+n]=i+1;
	}
	n = 2 * n;
	sort(L+1,L+1+n);
	sort(X+1,X+1+n);
	int s = unique(X+1,X+1+n)-X - 1;
	build(1,1,s-1);
	long long ans = 0;
	for(int i=1;i<n;i++){
		int l = lower_bound(X+1,X+1+s,L[i].x1)-X;
		int r = lower_bound(X+1,X+1+s,L[i].x2)-X;
		modify(1,l,r-1,L[i].tag);//传参向左偏移
		ans = ans + 1ll*tr[1].len*(L[i+1].y-L[i].y);
	}
	cout<<ans<<'\n';
}

这个代码只能过5个样例,请问大佬们是我板子的问题还是边界没有处理好?

2024/3/24 20:19
加载中...