codeforces519C Cram Time

In a galaxy far, far away Lesha the student has just got to know that he has an exam in two days. As always, he hasn’t attended any single class during the previous year, so he decided to spend the remaining time wisely.

Lesha knows that today he can study for at most a hours, and he will have b hours to study tomorrow. Note that it is possible that on his planet there are more hours in a day than on Earth. Lesha knows that the quality of his knowledge will only depend on the number of lecture notes he will read. He has access to an infinite number of notes that are enumerated with positive integers, but he knows that he can read the first note in one hour, the second note in two hours and so on. In other words, Lesha can read the note with number k in k hours. Lesha can read the notes in arbitrary order, however, he can’t start reading a note in the first day and finish its reading in the second day.

Thus, the student has to fully read several lecture notes today, spending at most a
hours in total, and fully read several lecture notes tomorrow, spending at most b hours in total. What is the maximum number of notes Lesha can read in the remaining time? Which notes should he read in the first day, and which — in the second?

Input

The only line of input contains two integers a and b (0≤a,b≤109) — the number of hours Lesha has today and the number of hours Lesha has tomorrow.

Output

In the first line print a single integer n (0≤n≤a) — the number of lecture notes Lesha has to read in the first day. In the second line print n distinct integers p1,p2,…,pn (1≤pi≤a), the sum of all pi should not exceed a

.

In the third line print a single integer m(0≤m≤b) — the number of lecture notes Lesha has to read in the second day. In the fourth line print m distinct integers q1,q2,…,qm (1≤qi≤b), the sum of all qi should not exceed b

.
All integers pi and qi should be distinct. The sum n+m should be largest possible.


在给定的时间中读尽可能多的纸条,第 i 个纸条需要 i 个单位时间。
现在考虑对纸条的选取。现记在这两天中能看过最多的纸条数为 x=n+m。那么考虑对任意可行长度为 x 的序列,如果在序列中存在一个编号大于 x 的纸条,那么在区间[1,x]内必然存在一个数 n ,使得 n 不在当前得序列中。那么,将这个大于 x 的纸条用 n 替换,由于替换后总耗时一定小于替换前的耗时,因而替换后的序列也是一个可行序列。重复这样的替换,直到不存在一个纸条的编号大于 x 。由此可知,必然会存在一个解,在这个解中任意的纸条编号都小于 x 。由于存在总时间的限制,故可以得到如下不等关系:

[x*(x+1)]/2<=a+b

根据这个不等关系解出 x 的值。其中 x 的最大值可由题目中数据的最大规模得出。
因为 a<=a+b ,故在区间[1,x]中必定存在一个序列,使得序列中所有元素的和等于 a 。所以,设计DFS算法,在区间[1,x]中找出这个序列,作为第一天的序列。根据之前所述,在区间[1,x]中剩余的元素就为第二天的序列。


#include <stdio.h>
#include <math.h>
#include <cstring>
#include <climits>
#include <algorithm>
using namespace std;

long long a,b;
long peak,len;
bool used[100240];
int first[100240];
bool seek(int star,int res,int dep);
int main(){
    scanf("%d %d",&a,&b);
    peak=((sqrt(1+8*(a+b))-1)/2);
    if(b==0){
        printf("%d\n",peak);
        for(int i=1;i<=peak;i++)
            printf("%d ",i);
        printf("\n0\n\n");
        return 0;
    }
    for(int i=0;i<=peak+10;i++)
        used[i]=false,first[i]=-1;
    len=0;
    if(a!=0){
        seek(peak,a,0);
        for(int i=0;first[i]!=-1;i++)
            len++;
        printf("%d\n",len);
        for(int i=0;i<len;i++)
            printf("%d ",first[i]);
        printf("\n");
    }else{
        printf("0\n\n");
    }
    printf("%d\n",peak-len);
    for(int i=1;i<=peak;i++)
        if(!used[i])
            printf("%d ",i);
    printf("\n");
    return 0;
}
bool seek(int star,int res,int dep){
    if(res==0)
        return true;
    bool sym=false;
    for(int i=star;i>0;i--){
        if(!used[i]){
            int num=res-i;
            if(num<0)
                continue;
            used[i]=true;
            first[dep]=i;
            if(seek(i-1,num,dep+1)){
                sym=true;
                break;
            }
            used[i]=false;
        }
    }
    return sym;
}


注意特判,即输入为0时。

猜你喜欢

转载自blog.csdn.net/white_156/article/details/83476154