Codeforces Round #631 (Div. 2)

A. Dreamoon and Ranking Collection

Dreamoon is a big fan of the Codeforces contests.
One day, he claimed that he will collect all the places from 1 to 54 after two more rated contests. It’s amazing!
Based on this, you come up with the following problem:
There is a person who participated in n Codeforces rounds. His place in the first round is a1, his place in the second round is a2, …, his place in the n-th round is an.
You are given a positive non-zero integer x.
Please, find the largest v such that this person can collect all the places from 1 to v after x more rated contests.
In other words, you need to find the largest v, such that it is possible, that after x more rated contests, for each 1≤i≤v, there will exist a contest where this person took the i-th place.
For example, if n=6, x=2 and a=[3,1,1,5,7,10] then answer is v=5, because if on the next two contest he will take places 2 and 4, then he will collect all places from 1 to 5, so it is possible to get v=5.
Input
The first line contains an integer t (1≤t≤5) denoting the number of test cases in the input.
Each test case contains two lines. The first line contains two integers n,x (1≤n,x≤100). The second line contains n positive non-zero integers a1,a2,…,an (1≤ai≤100).
Output
For each test case print one line containing the largest v, such that it is possible that after x other contests, for each 1≤i≤v, there will exist a contest where this person took the i-th place.
Example
inputCopy
5
6 2
3 1 1 5 7 10
1 100
100
11 1
1 1 1 1 1 1 1 1 1 1 1
1 1
1
4 57
80 60 40 20
outputCopy
5
101
2
2
60
Note
The first test case is described in the statement.
In the second test case, the person has one hundred future contests, so he can take place 1,2,…,99 and place 101 on them in some order, to collect places 1,2,…,101.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string> 
using namespace std;
typedef long long ll;
bool a[200];
int main()
{
	int t,n,x,q;cin>>t;
	while(t--)
	{
		memset(a,false,sizeof(a));
		scanf("%d%d",&n,&x);
		int maxx=-1;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&q);
			maxx=max(maxx,q);
			a[q]=true;
		}
		int flag=0,ans,i;
		for(i=1;i<=100;i++)
		{
			if(!a[i])
			{
				x--;
			}
			ans=i;
			if(x==0)
			{
				break;
			}
		}
		i++;
		for(;i<=100;i++)
		if(a[i])ans++;
		else break;
		ans+=x;
		cout<<ans<<endl;
	}
}

B. Dreamoon Likes Permutations

outputstandard output
The sequence of m integers is called the permutation if it contains all integers from 1 to m exactly once. The number m is called the length of the permutation.

Dreamoon has two permutations p1 and p2 of non-zero lengths l1 and l2.

Now Dreamoon concatenates these two permutations into another sequence a of length l1+l2. First l1 elements of a is the permutation p1 and next l2 elements of a is the permutation p2.

You are given the sequence a, and you need to find two permutations p1 and p2. If there are several possible ways to restore them, you should find all of them. (Note that it is also possible that there will be no ways.)

Input
The first line contains an integer t (1≤t≤10000) denoting the number of test cases in the input.

Each test case contains two lines. The first line contains one integer n (2≤n≤200000): the length of a. The second line contains n integers a1,a2,…,an (1≤ai≤n−1).

The total sum of n is less than 200000.

Output
For each test case, the first line of output should contain one integer k: the number of ways to divide a into permutations p1 and p2.

Each of the next k lines should contain two integers l1 and l2 (1≤l1,l2≤n,l1+l2=n), denoting, that it is possible to divide a into two permutations of length l1 and l2 (p1 is the first l1 elements of a, and p2 is the last l2 elements of a). You can print solutions in any order.

Example
inputCopy
6
5
1 4 3 2 1
6
2 4 1 3 2 1
4
2 1 1 3
4
1 3 3 1
12
2 1 3 4 5 6 7 8 9 1 10 2
3
1 1 1
outputCopy
2
1 4
4 1
1
4 2
0
0
1
2 10
0
Note
In the first example, two possible ways to divide a into permutations are {1}+{4,3,2,1} and {1,4,3,2}+{1}.
In the second example, the only way to divide a into permutations is {2,4,1,3}+{2,1}.
In the third example, there are no possible ways.
题意
给你一个长度为n的整型序列,问你能不能找到一些断点i,使a1~ai是一个1 ~n的序列,ai到an是一个1 ~ n-i的序列,输出两个序列的长度
思路
正向遍历一遍整个序列,如果满足a1到ai的最大值等于i,而且每个数都只出现一次(用桶排法标记一下),就说明i可以作为一个断点。
然后再反向遍历一遍,方法相同,标记断点,如果正向遍历标记的断点下标与反向标记的断点下标的差值为1,即i(正)+ 1 =i(反),则说明i可以作为一个断点
code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string> 
using namespace std;
typedef long long ll;
int a[200100]; 
bool flag[200001],temp1[200001],temp2[200001];
int x[200010],y[200010],ans;
int main()
{
	int t,n;cin>>t;
	while(t--)
	{
		cin>>n;
		ans=0;
		memset(flag,false,sizeof(flag));
		memset(temp1,false,sizeof(temp1));
		memset(temp2,false,sizeof(temp2));
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
		}
		int maxx=-1;
		for(int i=1;i<=n;i++)//正向遍历一遍 
		{
			if(flag[a[i]])break;//a[i]在序列中只能出现一次 
			maxx=max(maxx,a[i]);
			flag[a[i]]=1;
			if(maxx==i)//i可以作为一个断点 
			temp1[i]=1;
		}
		maxx=0; 
		memset(flag,false,sizeof(flag));
		for(int i=n;i>=1;i--)//反向遍历一遍 
		{
			if(flag[a[i]])break;
			maxx=max(maxx,a[i]);
			flag[a[i]]=1;
			if(maxx==n-i+1)//i可以作为一个断点 
			temp2[i]=1;
		}
		for(int i=1;i<n;i++)
		{
			if(temp1[i]&&temp2[i+1])
			x[ans]=i,y[ans++]=n-i;
		}
		cout<<ans<<endl;
		for(int i=0;i<ans;i++)
		{
			printf("%d %d\n",x[i],y[i]);
		}
	}
	return 0;
}

C. Dreamoon Likes Coloring

Dreamoon likes coloring cells very much.
There is a row of n cells. Initially, all cells are empty (don’t contain any color). Cells are numbered from 1 to n.
You are given an integer m and m integers l1,l2,…,lm (1≤li≤n)
Dreamoon will perform m operations.
In i-th operation, Dreamoon will choose a number pi from range [1,n−li+1] (inclusive) and will paint all cells from pi to pi+li−1 (inclusive) in i-th color. Note that cells may be colored more one than once, in this case, cell will have the color from the latest operation.
Dreamoon hopes that after these m operations, all colors will appear at least once and all cells will be colored. Please help Dreamoon to choose pi in each operation to satisfy all constraints.
Input
The first line contains two integers n,m (1≤m≤n≤100000).
The second line contains m integers l1,l2,…,lm (1≤li≤n).
Output
If it’s impossible to perform m operations to satisfy all constraints, print “’-1” (without quotes).
Otherwise, print m integers p1,p2,…,pm (1≤pi≤n−li+1), after these m operations, all colors should appear at least once and all cells should be colored.
If there are several possible solutions, you can print any.
Examples
inputCopy
5 3
3 2 2
outputCopy
2 4 1
inputCopy
10 1
1
outputCopy
-1
题意
给定一个n和m以及一个长度为m的整型数组L,n代表有n个格子,要求一个数组p,循环m次,第i次的时候,给pi~pi+li-1的格子涂上颜色i,颜色可以被覆盖,m次涂色之后要使m个颜色都要出现,而且n个格子上都要被涂色
思路
先把L数组求合,如果小于n就直接输出-1了,因为所有长度加起来都小于n,就肯定做不到全部格子涂色。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string> 
using namespace std;
typedef long long ll;
int a[100010];
ll s[100010];
int main()
{
	int t,n,m;
	ll sum=0;
	cin>>n>>m;
	bool flag=false;
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&a[i]);
		sum+=a[i];
		if(a[i]+i-1>n)
		flag=1;
	}
	if(flag||sum<n)//
	{
		printf("-1\n");
	}
	else 
	{
		for(int i=m;i>=1;i--){//
			s[i]+=a[i]+s[i+1];
		}
		for(int i=1;i<=m;i++)
		{
			ll temp=i;
			printf("%d ",max(temp,n-s[i]+1));
		}
		cout<<endl;
	}
	return 0;
}

D. Dreamoon Likes Sequences

outputstandard output
Dreamoon likes sequences very much. So he created a problem about the sequence that you can’t find in OEIS:
You are given two integers d,m, find the number of arrays a, satisfying the following constraints:
The length of a is n, n≥1
1≤a1<a2<⋯<an≤d
Define an array b of length n as follows: b1=a1, ∀i>1,bi=bi−1⊕ai, where ⊕ is the bitwise exclusive-or (xor). After constructing an array b, the constraint b1<b2<⋯<bn−1<bn should hold.
Since the number of possible arrays may be too large, you need to find the answer modulo m.
Input
The first line contains an integer t (1≤t≤100) denoting the number of test cases in the input.
Each of the next t lines contains two integers d,m (1≤d,m≤109).
Note that m is not necessary the prime!
Output
For each test case, print the number of arrays a, satisfying all given constrains, modulo m.
Example
inputCopy
10
1 1000000000
2 999999999
3 99999998
4 9999997
5 999996
6 99995
7 9994
8 993
9 92
10 1
outputCopy
1
3
5
11
17
23
29
59
89
0

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll num[1010];
ll ans[1010];
int main()
{
	int d,m,t;cin>>t;
	while(t--)
	{
		cin>>d>>m;
		memset(ans,0,sizeof(ans));
		int n=1,D=d,NUM=1;
		while(D)
		{
			num[n++]=min(NUM,d-NUM+1);//计算最高位在第n位的数的个数
			D/=2;NUM*=2; 
		}
		//for(int i=1;i<n;i++)
     	//printf("%d%c",num[i],i==n-1?'\n':' ');
     	for(int i=1;i<n;i++)
     	{
     		ans[i]+=ans[i-1];//最高位的数是第i位的数不选 
     		ans[i]%=m;
     		ans[i]+=num[i]%m;// 只选高位的数是第i位的数
     		ans[i]%=m;
     		ans[i]+=ans[i-1]*num[i];//每一位都选 
     		ans[i]%=m;
		}
		printf("%lld\n",ans[n-1]%m); 
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值