Codeforces gym101612 L.Little Difference(枚举+二分)

时间:2022-10-25 21:13:05

传送:http://codeforces.com/gym/101612

题意:给定一个数n(<=1e18),将n分解为若干个数的成绩。要求这些数两两之间的差值不能大于1。

分析:

若n==2^k,则答案一定是-1。

然后,考虑若n==a^k,枚举k,二分求a。若n==a^x*(a+1)^y,枚举x,y,二分求解a。

注意:两数相乘可能>1e18,特判。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<ll,ll> pll;
 5 typedef pair<pair<ll,ll>,ll> plll;
 6 const int maxn=1e6+10;
 7 const ll inf=1e18+1e6;
 8 ll n;
 9 vector<pll> g1;
10 vector<plll> g2;
11 ll mul(ll a,ll b){
12     if (a>=1.0*inf/b) return inf;
13     else return a*b;
14 }
15 ll _pow(ll a,ll b){
16     ll res=1,base=a;
17     while (b){
18         if (b&1) res=mul(res,base);
19         base=mul(base,base);
20         b>>=1;
21     }
22     return res;
23 }
24 ll solve(int k){
25     ll l=1,r=n,ans,mid;
26     while (l<=r){
27         mid=(l+r)>>1;
28         ll tmp=_pow(mid,k);
29         if (tmp==n) return mid;
30         if (tmp<n) l=mid+1; else r=mid-1;
31     }
32     return 2;
33 }
34 ll solve2(int x,int y){
35     ll l=1,r=n,ans,mid;
36     while (l<=r){
37         mid=(l+r)>>1;
38         ll tmp=_pow(mid,x),tmp2=_pow(mid+1,y);
39         if (mul(tmp,tmp2)==n) return mid;
40         if (mul(tmp,tmp2)<n) l=mid+1; else r=mid-1;
41     }
42     return 2;
43 }
44 int main(){
45     //freopen("little.in","r",stdin);freopen("little.out","w",stdout);
46     ios::sync_with_stdio(false);
47     cin >> n;
48     if (n==(n&(-n))) return cout << -1 << endl,0;
49     g1.clear(); g2.clear();
50     ll num=0;
51     // a^k
52     for(int i=1;i<=63;i++){
53         ll a=solve(i);
54         if (_pow(a,i)==n){
55             g1.push_back({i,a});
56         }
57     }
58     // a^x * (a+1)^y
59     for(int i=1;i<=63;i++){
60         for (int j=1;j<=63;j++){
61             ll a=solve2(i,j);
62             ll tmp=_pow(a,i),tmp2=_pow(a+1,j);
63             if (mul(tmp,tmp2)==n){
64                 g2.push_back({{i,j},a});
65             }
66         }
67     }
68     cout << g1.size()+g2.size() << endl;
69     for (auto i:g1){
70         ll tmp=i.first;
71         cout << tmp;
72         for (int j=0;j<tmp;j++) cout << " " << i.second;
73         cout << endl;
74     }
75     for (auto i:g2){
76         ll tmp=i.first.first+i.first.second;
77         cout << tmp;
78         tmp=i.first.first;
79         for (int j=0;j<tmp;j++) cout << " " << i.second;
80         tmp=i.first.second;
81         for (int j=0;j<tmp;j++) cout << " " << i.second+1;
82         cout << endl;
83     }
84     return 0;
85 }