2015多校联合训练赛 Training Contest 4 1008

 构造题:

        比赛的时候只想到:前面一样的数,后面 是类似1,2,3,4,5,6....t这 既是:t+1,t+1...,1,2,3,...t

        t+1的数目 可能 很多,

       题解时YY出一个N 然后对N  判断。 

       seg{Li*(Li-1)} = n*n+n-2*k=d;

       每次跑sqrt(n)找到 最近的 d ,D_new=d-Li*(Li-1);

       这样一定能解的:d 一定是偶数,Li*(Li-1)也一定是偶数,2*1=2;

      还有seg(Li)=n;

      当Li=1是 Li*Li-Li=0; 

      加入一些1就好。

     思路有了,建议自己实现一下。

   

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<string>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #include<cmath>
11 #include<iostream>
12 using namespace std;
13 typedef long long ll;
14 
15 #define N 10234567
16 int a[N];
17 int b[N];
18 
19 
20 int main()
21 {
22 
23 
24     int n;
25     freopen("input.txt","r",stdin);
26     freopen("out.txt","w",stdout);
27     while (scanf("%d",&n)!=EOF)  //注意我这里 K N 的位置相反
28    {
29      int t=0;
30      if (n<=100)//  特判 N<=100;
31      {
32         printf("%d
",n);
33         for (int i=1;i<n;i++) printf("%d ",1);
34         printf("%d
",1);
35      }
36      else
37      {
38         ll k=1;
39         for (int i=1;i<=sqrt(2*n)+123;i++) //由题解 随便指定一个 N--> 就是k
40         {
41             ll ttt=(ll) i*(i+1)/2-n;
42             if (ttt>=0)
43             {
44               k=i;
45               break;
46             }
47         }
48         k++;// 稍微大一点也没关系的
49         ll  tmp=k*(k+1)/2-n;//题解没除二 ,我除了 ,其实都是一样的
50 
51         while (tmp)//每次找一个p p*(p-1)<=tmp;
52         {
53            int pos=0;
54            for (int i=1;i<=sqrt(tmp)+123;i++)
55            {
56             if (tmp>=(ll) i*(i-1)/2) pos=i;
57             else break;
58            }
59            a[++t]=pos;
60            tmp-=(ll) pos*(pos-1)/2;
61         }
62 
63         int res=0;
64         for (int i=1;i<=t;i++) res+=a[i];
65 
66 
67         if (res<k) //res一定<=k验证的很多数据
68         for (int i=1;i<=k-res;i++)
69         a[++t]=1;
70 
71         int id=0;
72         for (int i=1;i<=t;i++)
73         for (int j=1;j<=a[i];j++)
74         b[++id]=i;
75 
76         printf("%d
",id);
77 
78         for (int i=1;i<id;i++) printf("%d ",b[i]);
79         printf("%d
",b[id]);
80      }
81    }
82    return 0;
83 }
View Code
原文地址:https://www.cnblogs.com/forgot93/p/4691713.html