Comments

Can u please elaborate your approach a little bit more. I am struck in this problem from so long.

Auto comment: topic has been updated by someone_lunatic_lyk_hell (previous revision, new revision, compare).

I'm in dude!! Let's do it!

Please can u write a separate blog so that the whole community can know how this guy is killing the whole spirit of competitive programming. I think his main account should immediately be blocked.

On awoo → Codeforces Round 916 (Div. 3), 3 years ago
+3

The core idea revolves around determining the number of ways to activate bulbs in such a way that disjoint ranges are covered. The approach involves finding** sets of bulbs that, when activated, cover a specific disjoint range**.

Spoiler

Let's denote the number of disjoint ranges as 'k.' For each range, we aim to identify the bulbs whose activation covers the entire range. Through some careful considerations, we conclude that we need to eliminate bulbs that do not contribute to extending the current segment. This elimination process is efficiently executed using prefix hash values and storing the last pointer for each unique prefix value.

To illustrate this concept, consider the arrangement of bulbs: 1 2 2 3 1 3. The number of disjoint ranges in this case is one. Building prefix hash values results in pre[0]=1, pre[1]=1^2, pre[2]=1, pre[3]=1^3, pre[4]=3, pre[5]=0. After activating the first bulb, we jump to the bulb at index 1 + (last[1]=2).

Spoiler

The hashing technique employed here, as introduced by jiangly, is a so cool and unique that when understood properly can be generalized to solve a variety of other problems involving segment merging or ranges.

const int mod= 998244353;

std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());

void solve(){	
	int n;
	cin>>n;
	vector<int>col(2*n);
	for(int i=0;i<2*n; i++){
		cin>>col[i];
		col[i]--;
	}
		
	//now through random number generator
	//let's generate for each colour a unique random val
	
	vector<int>hashVal(n);
	for(int i=0; i<n; i++)hashVal[i]= rng();
	
	//now make a prefix xor array of these hashed values
	//so that we can effectively know how many 
	//ranges of 0 to 0 we have
	//number of min sets= number of ranges
	
	vector<int>prefixXor(2*n,0);
	prefixXor[0]= hashVal[col[0]];
	for(int i=1; i<2*n; i++)prefixXor[i]= prefixXor[i-1]^hashVal[col[i]];
	
	//number of zeroes = no of ranges
	int ans= count(prefixXor.begin(),prefixXor.end(),0);
	
	int ways=1;
	map<int,int>jumpTo;
	for(int i=0; i<2*n; i++){
		jumpTo[prefixXor[i]]= i;
	}
	
	for(int i=0; i<2*n;){
		//start of range-> prefixXor= hashedVal[i]
		
		if(prefixXor[i]==hashVal[col[i]]){
			//inside new range
			//jump directly all the ranges lying
			//completely inside it and not helping in
			//extending it
			
			int active=1;
			int j=i;
			while(prefixXor[j]!=0){
				j= jumpTo[prefixXor[j]];
				active++;
				if(prefixXor[j]==0)break;
				j++;
			}
			ways= (ways*active)%mod;
			i=j+1;
		}
	}
	cout<<ans<<" "<<ways<<endl;
	return;
}

Will try for expert!! Current rating is 1273; And no. of problem solved is 467. Will try to raise this count to 800+. Let's see... !!!!!!