杭电多校第三场

杭电多校第三场

D-不相交线段最多

Problem D. Tokitsukaze and Multiple
Tokitsukaze has a sequence of length n, denoted by a.
Tokitsukaze can merge two consecutive elements of a as many times as she wants. After each operation,
a new element that equals to the sum of the two old elements will replace them, and thus the length of a
will be reduced by 1.
Tokitsukaze wants to know the maximum possible number of elements that are multiples of p she can get
after doing some operations (or doing nothing) on the sequence a.

Input
There are several test cases.
The first line contains an integer T (1 ≤ T ≤ 20), denoting the number of test cases. Then follow all the
test cases.
For each test case, the first line contains two integers n and p (1 ≤ n; p ≤ 105), denoting the length of the
sequence and the special number, respectively.
The second line contains n integers, where the i-th integer ai (1 ≤ ai ≤ 105) is the i-th element of a.
It is guaranteed that the sum of n in all test cases is no larger than 106.

Output
For each test case, output in one line the maximum possible number of elements that are multiples of p
after doing some operations.

Example

standard input standard output
2 5 3 2 1 3 2 1 3 1 123 456 789 3 3

思路

贪心。遇到和为p的线段就选中。类比观看节目问题,一定选择剩余没有选择的节目中结束时间最早的那个。巧妙地用set判断当前余数是不是出现过,如果出现过就一定包含了p。

C++(AC)

int main(){
	int t,n,p,a[100010],now,ans,sum[100010],temp;
	std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>t;
	set <int> s;
	while (t--)
	{
		cin>>n>>p;
		rep(i,1,n)
		  cin>>a[i];
		ans=0;
		now=0;
		sum[0]=0;
		s.insert(0);
		rep(i,1,n)
		  sum[i]=(sum[i-1]+a[i])%p;
		rep(i,1,n)
		{
			temp=(sum[i]-sum[now])%p;
			if (s.count(temp))
			{
				ans++;
				s.clear();
				s.insert(0);
				now=i;
			}
			else
			  s.insert(temp);
		}
		cout<<ans<<endl;
	}
	return 0;
}

E-并查集+排列组合

Problem E. Little W and Contest

There are n members in our ACM club. Little W wants to select three persons from our club to form
a new team taking part in provincial ACM contests, as it is known by all of us that any ACM contest
requires a normal team to have three members.
Little W has divided our club members into two role groups. The first group contains only readers
who dedicate themselves to reading problems during contests, though sometimes they may also prepare
drinking and food for the team. For the sake of measurement, we define the power of a reader as 1. The
second part contains only coders who code and test programs all the time, and similarly, we define the
power of a coder as 2.
Little W thinks it will be a tremendous disaster when a team has two readers because in that case, the
total power of this team is less than 5 and thus it has a high risk to fail the contest. To avoid that, Little
W thinks a new team must have at least two coders.
Additionally, Little W defines the relationship between club members with transitivity. That is, for every
three members A, B, and C, if A is familiar with B, and B is familiar with C, then A will be familiar with
C through B instantly. Based on the definition, it is forbidden for the team to have any two members
familiar with each other.
At first, no member of our club is familiar with any other, and then Little W will repeatedly make an
introduction between two members who are currently strangers to each other until each member is familiar
with all the others. During this process, there will be exactly (n - 1) introductions.
Now, for i = 1; 2; : : : ; n, Little W wants you to count the combinations of three club members that can form
a new team after the first (i - 1) introductions have been made. However, the numbers of combinations
may be quite gigantic, so you just need to report each number in modulo (109 + 7).

Input
There are several test cases.
The first line contains an integer T (1 ≤ T ≤ 10), denoting the number of test cases. Then follow all the
test cases.
For each test case, the first line contains an integer n (1 ≤ n ≤ 105), denoting the number of members in
this club.
The second line contains n integers consisting of only 1 and 2, where the i-th integer represents the power
of the i-th member.
The next (n - 1) lines describe all introductions in chronological order of occurrence, where each line
contains two integers u and v (1 ≤ u; v ≤ n; u 6= v), representing an introduction between the u-th
member and the v-th member, who are currently strangers to each other.
It is guaranteed that the sum of n is no larger than 106.

Output
For each test case, output n lines, where the i-th line contains an integer, denoting the number of
combinations of three club members, in modulo (109 + 7), that can form a new team after the first
(i - 1) introductions have been made.

Example

standard input standard output
15 2 2 2 1 1 4 5 1 4 2 1 3 2 7 7 3 0 0

思路

用并查集找到每个小团体的根节点,根节点记录该小团体power=1&&2的个数,每次合并时相加来维护power个数。计算时每次累计减,匹配方案共2 2 1、2 2 2两种

减的时候从第一个人的小团体中power=2中选1个,第二个人的小团体中power=1中选一个,然后从谁都不认识的power=2中选一个组成一个方案;

然后第二个人的小团体中power=2中选1个,第一个人的小团体中power=1中选一个,然后从谁都不认识的power=2中选一个组成一个方案;

接下来从两个团体中power=2的中各选一个,再从都不认识的power=2选1个,

还从两个团体中power=2的中各选一个,再从都不认识的power=1选1个

就是2 2 1匹配方案中第一团体和第二团体共2 1、1 2、2 2三种子方案,2 2 2只有2 2一种方案

自己团体就不要自我组合了,因为在合并前已经算过了,这是累计减。

在算mod时注意到结果不会超过long long范围,所以就输出取余就好,其他时候不要随便取余,不然会不统一。

C++(AC)

ll fa[100010],a[100010],c1[100010],c2[100010];ll cnt1,cnt2;
int find(int x){
	if(fa[x]==x)return x;
	return fa[x]=find(fa[x]);
}
void merge(int x,int y){
	x=find(x),y=find(y);
	if(x!=y){
		fa[x]=y;
		c1[y]=c1[x]+c1[y];
		c2[y]=c2[x]+c2[y];
	}
}
void solve(){
	int n,x,y;cin>>n;
	cnt1=0,cnt2=0;
	rep(i,1,n)c1[i]=c2[i]=0;
	rep(i,1,n){
		cin>>a[i];
		fa[i]=i;
		if(a[i]==1)cnt1++,c1[i]++;
		else cnt2++,c2[i]++;
	}
	ll sum=0;
	ll t1=0,t2=0;
	sum=(cnt2*(cnt2-1LL)/2*(cnt2-2)/3+cnt2*(cnt2-1LL)/2*cnt1);
	cout<<sum%mod<<endl;
	rep(i,1,n-1){
		cin>>x>>y;
		x=find(x),y=find(y);
		sum-=(c2[x]*c1[y]+c1[x]*c2[y]+c2[x]*c2[y])*(cnt2-c2[x]-c2[y]);
		sum-=(c2[x]*c2[y])*(cnt1-c1[x]-c1[y]);
		cout<<sum%mod<<endl;
		merge(x,y);
	}
} 
int main(){
	std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	TT(){
		solve();
	}
	return 0;
}

I-括号匹配

Problem I. Parentheses Matching
Given a string P consisting of only parentheses and asterisk characters (i.e. “(”, “)” and “”), you are
asked to replace all the asterisk characters in order to get a balanced parenthesis string with the shortest
possible length, where you can replace each “
” by one “(”, or one “)”, or an empty string “”.
A parenthesis string S is a string consisting of only parentheses (i.e. “(” and “)”), and is considered balanced
if and only if:
• S is an empty string, or
• there exist two balanced parenthesis strings A and B such that S = AB, or
• there exists a balanced parenthesis string C such that S = (C).
For instance, “”, “()”, “(())”, “()()”, “()(())” are balanced parenthesis strings.
Due to some notorious technical inability, if there are several solutions with the shortest possible length,
then you have to report the smallest possible one in lexicographical order.
For every two different strings A and B of the same length n, we say A is smaller than B in lexicographical
order if and only if there exists some integer k such that:
• 1 ≤ k ≤ n, and
• the first (k - 1) characters of A and that of B are exactly the same, and
• the k-th character of A is smaller than that of B.
For instance, “()(())” is smaller than “()()()”, and in this case, k = 4.
Input
There are several test cases.
The first line contains an integer T (1 ≤ T ≤ 105), denoting the number of test cases. Then follow all the
test cases.
For each test case, the only line contains a string of length n (1 ≤ n ≤ 105), denoting the string P that
consists of only parentheses and asterisk characters.
It is guaranteed that the sum of n in all test cases is no larger than 5 × 106.
Output
For each test case, output in one line “No solution!” (without quotes) if no solution exists, or otherwise
the smallest possible solution in lexicographical order. Note that the output characters are case-sensitive.
Example

C++(AC)

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<string.h>
#include<stack>
#define ll long long
using namespace std;

string a;
stack<int>st2;
int pos[5000010];

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int l=0,r=0;
		cin>>a;
		int ma=0;
		while(!st2.empty()) st2.pop();
		for(int i=0;i<a.length();i++)
		{
			if(a[i]=='*') {
				pos[r++]=i;
			}
			else if(a[i]==')'){
				if(!st2.empty()){
					st2.pop();
				}
				else if(l<r)
				{
					a[pos[l++]]='(';
				}
				else {
					ma=1;
					break;
				}
			}
			else if(a[i]=='(')
			{
				st2.push(i);
			}
		}
		if(ma==1) {
			cout<<"No solution!\n";
			continue;
		}
		ma=0;
		while(!st2.empty())
		{
			int ind1=st2.top();
			st2.pop();
			if(l>=r) {
				ma=1;
				break;
			}
			if(ind1<=pos[r-1]){
				a[pos[r-1]]=')';
				r--;
			}
			else {
				ma=1;
				break;
			}
		}
		if(ma==1) cout<<"No solution!\n";
		else {
			for(int i=0;i<a.length();i++) 
			{
				if(a[i]!='*') cout<<a[i];
			}
			cout<<"\n";
		}
		
	}
	return 0;
 } 
posted @ 2020-08-02 23:42  IamIron-Man  阅读(238)  评论(0)    收藏  举报