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",n); 33 for (int i=1;i<n;i++) printf("%d ",1); 34 printf("%d\n",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\n",id); 77 78 for (int i=1;i<id;i++) printf("%d ",b[i]); 79 printf("%d\n",b[id]); 80 } 81 } 82 return 0; 83 }
随性Code