Codeforces Round #767 (Div. 2) C D

Posted by Sergeant on Tue, 25 Jan 2022 22:48:44 +0100

Codeforces Round #767 (Div. 2) C D

The night of the game was too tired. I wanted to sleep first. When I heard the alarm clock, I found that the game would start in two minutes.. In addition, I haven't been training in the past few days (next time, I must be TAT), and I don't have much confidence in my ability to do questions, so I'm ll "hoping" Everyone fell asleep while taking part in the game. Wake up and see how div2 is all blue? It turned out that both purple name and orange name went to play div1. I was the only one who didn't play this game. Out of encouragement for my good performance in acm competition training class A, ll broke an example for my young name and allowed me to return to the training team. Standing at the turning point of fate, where is the reason not to work hard? How can "Hope" mean literally? There is no special training arrangement in winter vacation. The meaning of "hope to participate in cf" can only be the training tasks that must be completed.

Game link

https://codeforces.com/contest/1629

C

meaning of the title

Given 2e5 numbers of sequence a, it is required to construct a sequence b with the largest dictionary order. The construction rules are as follows: select the numbers in the first k a each time, find their mex value, insert them at the end of b, delete them in a, and change the subscript.

thinking

There is a very important property: the mex value of a[1...i] is monotonous with the increase of i.
If a [1.. i] > a [1.. i-1], then i must be divided into the previous segment and segmented (disconnected) here

It's easy to think of O(n^2)
Enumerate the subscript i in a from back to front to calculate a[1..i] and a[1..i-1]. If the values are different, I must be added to the previous paragraph

O(n^2)

Click to view the code
		vector<int>ans;
		int st=1;
		while(st&lt;=n){
			for(int i=n;i&gt;=st;i--){    //Special judgment 
				int mx=mex(st,i);int mn=mex(st,i-1);
				if(mx&gt;mn||st==n&amp;&amp;mx==mn){
					ans.push_back(mx);
					st=i+1;
				}
			}
		}
		printf("%d\n",ans.size());
		for(auto i:ans){
			printf("%d ",i);
		}
		puts("");

However, it will time out


O(n) method: the value added to b every time must be the mex value of the whole sequence A. therefore, find mex(a) first, and then delete the value in the first k (their mex is the largest and K is the smallest). See code for details

O(n)

Click to view the code
		//Find mex 
		int mex=0;
		for(int i=0;i&lt;=n;i++){
			if(!cnt[i]){
				mex=i;
				break;
			}
		}
		//Delete the first k (their mex is the largest and K is the smallest) 
		int cntt=0;
		for(int i=0;i&lt;=n;i++) tem[i]=0;
		bool flag=0;
		for(int i=1;i&lt;=n;i++){
			if(mex==0){
				ans.push_back(0);
				continue;
			}
			if(!tem[a[i]]&amp;&amp;a[i]&lt;=mex-1){
				tem[a[i]]++;
				cntt++;   //If cntt happens to appear k times, it can be segmented (cntt must be less than mex before counting 
				if(cntt==mex){
					cntt=0;
					ans.push_back(mex);
					for(int j=0;j&lt;mex;j++) cnt[j]-=tem[j],tem[j]=0;
					for(int j=0;j&lt;=n;j++){
						if(!cnt[j]){
							mex=j;
							break;
						}
					}
				} 
			}
			else tem[a[i]]++;
		}
		printf("%d\n",ans.size());
		for(auto i:ans){
			printf("%d ",i);
		}
		puts("");
<br>Learned the students' code and found that O(nlogn)practice<br />
1.STL<br>
2.Chairman tree</p>

D

meaning of the title

Given 1e5 strings, the length of each string is no more than 3 (the length is 1 ~ 3), delete some characters from them, and ask whether the remaining characters can be connected together to form a palindrome string

thinking

Map string to bool type with map
An important property: the shortest palindrome string can only be composed of a/ab+ba+abc+cba+ab+cba+abc+ba
And there are also requirements for asymmetric string order

Click to view the code
		scanf("%d",&amp;n);
		for(int i=1;i&lt;=n;i++) cin&gt;&gt;s[i],m[s[i]]++;
		bool flag=0;
		string tem1,tem2,tem3;
		for(int i=0;i&lt;26;i++){
			tem1="";
			char ch1=(i+'a');
			tem1+=ch1;
			
			for(int j=0;j&lt;26;j++){
				tem2="";
				char ch2=(j+'a');
				tem2+=ch2; 
				
				for(int k=0;k&lt;26;k++){
					tem3 = "";
					char ch3=(k+'a');
					tem3+=ch3;
					if(m[tem3]&gt;=1){
						flag=1;
						break;
					}
					if(m[tem2+tem3]&gt;=1&amp;&amp;m[tem3+tem2]&gt;=1){
						flag=1;
						break;
					}
					if(m[tem1+tem2+tem3]&gt;=1&amp;&amp;m[tem3+tem2+tem1]&gt;=1){
						flag=1;
						break;
					}
				}
				if(flag) break;
			}
			if(flag) break;
		}
		
		map&lt;string,int&gt;mp;
		for(int i=1;i&lt;=n;i++) mp[s[i]]++;
		for(int i=1;i&lt;=n;i++){
			if(s[i].length()==2){
				for(int j=0;j&lt;26;j++){
					char ch=(j+'a');
					string pre=s[i];
					reverse(pre.begin(),pre.end());
					pre=(string)(pre+ch);
					string last=(string)(ch+pre.substr(0,2));
					if(mp[pre]==0&amp;&amp;m[pre]&gt;=1||mp[last]){
						flag=1;
						break;
					}
				}
			}
			if(s[i].length()==3){
				for(int j=0;j&lt;26;j++){
					char ch=(j+'a');
					string tem=s[i];
					reverse(tem.begin(),tem.end());
					tem=tem[0]+tem[1];
					string last=tem.substr(1,2);
					if(mp[tem]==0&amp;&amp;m[tem]&gt;=1||mp[last]){
						flag=1;
						break;
					}
				}
			}
			if(flag) break;
			mp[s[i]]--;
		}
		
		if(flag){
			puts("yes");
		}
		else puts("no");
		m.clear();