Submission #1271566

#TimeUsernameProblemLanguageResultExecution timeMemory
1271566thuhienneHeavy Light Decomposition (CCO24_day2problem2)C++20
25 / 25
600 ms36928 KiB
#include <bits/stdc++.h>
using namespace std;

const int mod = 1e6 + 3;

int n,arr[500009];

int odd[500009],even[500009];
int freq[500009];
bool dmm[500009];

void findrange() {
	//odd
	int pt = 1;
	for (int i = 1;i <= n;i++) {
		freq[arr[i]]++;
		if (i % 2 != 0) {
			while (freq[arr[i]] > 1) {
				freq[arr[pt]]--;
				if (pt % 2 != 0) dmm[arr[pt]] = 0;
				pt++;
			}
			dmm[arr[i]] = 1;
		} else {
			while (dmm[arr[i]]) {
				freq[arr[pt]]--;
				if (pt % 2 != 0) dmm[arr[pt]] = 0;
				pt++;
			}
		}
		odd[i] = pt;
	}
	//even
	for (int i = 1;i <= n;i++) freq[i] = dmm[i] = 0;
	pt = 1;
	for (int i = 1;i <= n;i++) {
		freq[arr[i]]++;
		if (i % 2 == 0) {
			while (freq[arr[i]] > 1) {
				freq[arr[pt]]--;
				if (pt % 2 == 0) dmm[arr[pt]] = 0;
				pt++;
			}
			dmm[arr[i]] = 1;
		} else {
			while (dmm[arr[i]]) {
				freq[arr[pt]]--;
				if (pt % 2 == 0) dmm[arr[pt]] = 0;
				pt++;
			}
		}
		even[i] = pt;
	}
}

int dp[500009],predp[500009];
int sumdp(int l,int r) {
	l--,r--;
	if (l == 0) return predp[r];
	return (predp[r] - predp[l - 1] + mod)%mod;
}


//segment tree
pair <int,int> st[2][500009 * 4];
//.first: co bn segment phu doan l,r
//.second: tong cac dp duoc phu boi it nhat 1 doan trong doan l,r

void changeseg(int id,int l,int r,int u,int v,int val,pair <int,int> st[]) {
	if (l > v || r < u) return;
	if (l >= u && r <= v) {
		st[id].first += val;
		if (st[id].first > 0) st[id].second = sumdp(l,r);
		else if (l == r) st[id].second = 0;
		else st[id].second = (st[id*2].second + st[id*2+1].second)%mod;
		return;
	}
	int mid = (l + r) >> 1;
	changeseg(id*2,l,mid,u,v,val,st);
	changeseg(id*2+1,mid+1,r,u,v,val,st);
	if (st[id].first > 0) st[id].second = sumdp(l,r);
	else st[id].second = (st[id*2].second + st[id*2+1].second)%mod;
}
void updatevalue(int id,int l,int r,int pos) {
	if (l > pos || r < pos) return;
	if (l == r) {
		if (st[0][id].first > 0) st[0][id].second = sumdp(l,r);
		else st[0][id].second = 0;
		if (st[1][id].first > 0) st[1][id].second = sumdp(l,r);
		else st[1][id].second = 0;
		return;
	}
	int mid = (l + r) >> 1;
	
	updatevalue(id*2,l,mid,pos);
	updatevalue(id*2+1,mid+1,r,pos);
	
	if (st[0][id].first > 0) st[0][id].second = sumdp(l,r);
	else st[0][id].second = (st[0][id*2].second + st[0][id*2+1].second)%mod;
	
	if (st[1][id].first > 0) st[1][id].second = sumdp(l,r);
	else st[1][id].second = (st[1][id*2].second + st[1][id*2+1].second)%mod;
}
int get(int id,int l,int r,int u,int v,pair <int,int> st[]) {
	if (l > v || r < u) return 0;
	if (st[id].first > 0) return sumdp(max(l,u),min(r,v));
	if (l >= u && r <= v) return st[id].second;
	int mid = (l + r) >> 1;
	return (get(id*2,l,mid,u,v,st) + get(id*2+1,mid+1,r,u,v,st))%mod;
}


int prevodd[500009],preveven[500009];
int prevodd2[500009],preveven2[500009];

void caldp() {
	dp[0] = 1;
	predp[0] = 1;
	for (int i = 1;i <= n;i++) {
		int l,r;
		//Range 1: a[i] la phan tu light
		l = (i % 2 == 0 ? even[i] : odd[i]),r = i;
		
		//tong cach tao ra dp i la so cach tao ra dp x (x thuoc [l - 1,r - 1])
		//tru di nhung thang nao ma [x + 1,i] co 1 thang khac tinh cl vs i
		//la light
		dp[i] = (dp[i] + sumdp(l,r))%mod;
		dp[i] = (dp[i] - (i % 2 == 0 ? get(1,1,n,l,r,st[1]) : get(1,1,n,l,r,st[0])) + mod)%mod;
		
		//update range prev ai, ai
		if (i % 2 == 0) {
			if (preveven[arr[i]] == 0) {
				changeseg(1,1,n,1,i,1,st[0]);
				preveven[arr[i]] = i;
			}
			else {
				changeseg(1,1,n,preveven2[arr[i]] + 1,preveven[arr[i]],-1,st[0]);
				changeseg(1,1,n,preveven[arr[i]] + 1,i,1,st[0]);
				preveven2[arr[i]] = preveven[arr[i]];
				preveven[arr[i]] = i;
			}
		} else {
			if (prevodd[arr[i]] == 0) {
				changeseg(1,1,n,1,i,1,st[1]);
				prevodd[arr[i]] = i;
			}
			else {
				changeseg(1,1,n,prevodd2[arr[i]] + 1,prevodd[arr[i]],-1,st[1]);
				changeseg(1,1,n,prevodd[arr[i]] + 1,i,1,st[1]);
				prevodd2[arr[i]] = prevodd[arr[i]];
				prevodd[arr[i]] = i;
			}
		}
		//Range 2: a[i] la phan tu heavy -> a[i - 1] la light
		if (i > 1 && arr[i] != arr[i - 1]) {
			l = (i % 2 == 0 ? odd[i - 1] : even[i - 1]),r = (i % 2 == 0 ? even[i] : odd[i]) - 1;
			if (l <= r) {
				dp[i] = (dp[i] + sumdp(l,r))%mod;
				dp[i] = (dp[i] - (i % 2 == 0 ? get(1,1,n,l,r,st[0]) : get(1,1,n,l,r,st[1])) + mod)%mod;
			}
		}
		predp[i] = (predp[i - 1] + dp[i])%mod;
		updatevalue(1,1,n,i + 1);
//		cout << dp[i] << " ";
	}
	cout << dp[n];
}

int main() {
	ios_base::sync_with_stdio(0);cin.tie(nullptr);
	//freopen(".inp","r",stdin);
	//freopen(".out","w",stdout);
	cin >> n;
	for (int i = 1;i <= n;i++) cin >> arr[i];
	findrange();
	caldp();
}

/*
  Nho doi vai em gay
			  co gai ay ngoi duoi goc pho nen tho ...
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...