CF 1305E. Kuroni and the Score Distribution

题目大意:题目给定两个数n和m(1<=n<=5000,0<=m<=1e9)要求构造一个数列A,A中元素

  1. 大于等于1,小于等于1e9且满足严格递增
  2. 满足ai+aj=ak的(i,j,k)恰好有m个

如果有没有这样的A输出-1。

分析:如果ai和aj确定,那么ak唯一。也可以说任意两个可以决定第三个。

首先可以猜想当A为1到n的连续自然数时这样的三元组最大。(容易用数学归纳法证明。利用下面红字得到的结论,一个一个加。em。。。)

假如前s个数已经确定为1到s的自然数按顺序的排列,当增加第s+1个数时,满足条件的(x,y,s+1)的个数就是满足as+1-y=x<y的y的个数(已知a1到as就是1到s的自然数,所以ax=x,ay=y),即满足 as+1<2*y 的y的个数。由此可以确定as+1对三元组个数的影响

同时也能得到这样的结论:

用数列Sn表示从1到n 的n个自然数按顺序排列而成的数列可以找到所有满足条件的三元组的数量。那么有:Sn+1-Sn=n/2(向下取整)。

可以先用1,2,3。。。来填充数组,超过时按上面红色的规则添加下一个数。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX_N=5000+20;
 5 int n,m;
 6 LL a[MAX_N];
 7 int main()
 8 {
 9     int tmp=1e9;
10     scanf("%d%d",&n,&m);
11     if(m==0){
12         for(int i=n;i>=1;i--)   a[i]=tmp,tmp-=1;
13         for(int i=1;i<=n;i++)   printf("%d ",a[i]);
14     }
15     else{
16         int i;
17         for(i=1;i<=n;i++){
18             if(m>=(i-1)/2)  a[i]=i,m-=(i-1)/2;
19             else break;
20         }
21         if(i>n&&m){printf("-1\n");}
22         else{
23             int cur;
24             for(cur=1;;cur++)   if(a[cur]==0)   break;
25             if(m==0){
26                 for(int j=n;j>=cur;j--)a[j]=tmp,tmp-=a[cur-1]+3;
27             }
28             else {
29                 a[cur]=a[cur-m]+a[cur-m-1];
30                 for(int j=n;j>cur;j--)a[j]=tmp,tmp-=a[cur]+3;
31             }
32             for(int i=1;i<=n;i++)   printf("%d ",a[i]);
33         }
34     }
35 }

 欢迎转载和引用

posted on 2020-03-04 22:22  num73  阅读(101)  评论(0编辑  收藏  举报