线段树被卡了,只有 70 pts,有什么降低常数的方法吗?
查看原帖
线段树被卡了,只有 70 pts,有什么降低常数的方法吗?
1137394
Hyvial楼主2025/7/24 10:00

测试信息

#include <bits/stdc++.h>
#define PII pair <int, int>
#define int long long
#define ST string
#define DB double

#define ls (x << 1)
#define rs ((x << 1) | 1)
#define mid ((t[x].l + t[x].r) >> 1)

#define fr(x, y, z) for(int x = y; x <= z; x ++ )
#define dfr(x, y, z) for(int x = y; x >= z; x -- )

using namespace std;

const int N = 1e6 + 10 , MOD = 1e9 + 7;
int n, a[N], na[N], num;
map <int, int> lst; 

struct Node
{ int sum, psum, l, r, tg; } t[N << 2];

Node operator + (Node x, Node y)
{ return {(x.sum + y.sum) % MOD, (x.psum + y.psum) % MOD, x.l, y.r, 0}; }

void init(int x, int tl, int tr)
{
	t[x] = {0, 0, tl, tr, 0};
	if(tl == tr) return ;
	init(ls, tl, mid);
	init(rs, mid + 1, tr);
}

void upoint(int x, int k)
{
	int len = t[x].r - t[x].l + 1;
	t[x].tg = (t[x].tg + k) % MOD;
	t[x].psum = (t[x].psum + 2 * k * t[x].sum % MOD + k * k * len % MOD) % MOD;
	t[x].sum = (t[x].sum + k * len % MOD) % MOD;
}

void pushdown(int x)
{ upoint(ls, t[x].tg), upoint(rs, t[x].tg), t[x].tg = 0; }

void update(int x, int l, int r, int k)
{
	if(l <= t[x].l && t[x].r <= r)
	{ upoint(x, k);  return ; }
	
	pushdown(x);
	if(l <= mid) update(ls, l, r, k);
	if(mid < r) update(rs, l, r, k);
	t[x] = t[ls] + t[rs];
}

Node query(int x, int l, int r)
{
	if(l <= t[x].l && t[x].r <= r)
		return t[x];
	
	pushdown(x);
	Node res; res.sum = res.psum = 0;
	if(l <= mid) res = res + query(ls, l, r);
	if(mid < r) res = res + query(rs, l, r);
	return res;
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin >> n; init(1, 1, n);
	fr(i, 1, n) cin >> a[i];
	
	int res = 0;
	fr(i, 1, n)
	{
		if(!lst.count(a[i])) num ++ ;
		else update(1, lst[a[i]], i - 1, -1);
		lst[a[i]] = i;
		
		Node qry = query(1, 1, i - 1);
		res = ((res + num * num * i % MOD - 2 * num * qry.sum % MOD + qry.psum) % MOD + MOD) % MOD;
		update(1, i, i, num);
	}
	
	cout << res << '\n';
	
	return 0;
}

2025/7/24 10:00
加载中...