-
结论:设之前的位置为
,然后删除位置坐标为
的倍数的数,那么原来第
个数的位置变为:
-
变形可以得到
,意思是之前的位置等于现在的位置加上删除数字的个数
删除数字的个数等于
,为什么是
,因为如果
,则算出来的
一定不是
的倍数,否则有可能是
的倍数
故可以
时间复杂度一步步算出
:
总代码:
也可以用二分来做:上面的代码用的是
,可以
时间复杂度一步步算出
。那也可以用
,因为满足单调性:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
void solve(){
int x, y, k; cin >> x >> y >> k;
if(y == 1){
cout << "-1" << endl;
return ;
}
for(int i = 1; i <= x; i ++){
k = k + (k - 1) / (y - 1);
if(k > 1000000000000){
cout << "-1" << endl;
return ;
}
}
cout << k << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
cin >> tt;
while(tt --) solve();
return 0;
}
也可以用二分来做:上面的代码用的是
总代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
int x, y, k;
bool check(int pos){
for(int i = 1; i <= x; i ++) pos -= pos / y;
if(pos >= k) return true;
else return false;
}
void solve(){
cin >> x >> y >> k;
int l = 1, r = 1000000000000, ans = -1;
while(l <= r){
int mid = (l + r) / 2;
if(check(mid)){
ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
cout << ans << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
cin >> tt;
while(tt --) solve();
return 0;
}
第一段代码的时间复杂度为
,第二段代码的时间复杂度为
,在
条件下都能通过
困难版本则是将
的范围提升至
次方
那么需要保证从
开始累加了
次
后,
才会发生变化,所以
累加了
次后的
仍然与一开始的
值相同,所以有:
首先令
,则
公式的计算.....
因为
是整数,所以
解得
,所以
的最大值就为
核心代码:
如果
了,那么无论加多少次,都灭有变化,进入死循环,所以
推出
如果
,表示到达下一次的边界情况,仍然会死循环,所以设置
,让其至少操作
次
然后
位置累加,
减去操作次数
while(x > 0){
int t = (k - 1) / (y - 1);
if(t == 0) break;
int cnt = ((t + 1) * (y - 1) - k + t) / t;
cnt = min(cnt, x);
if(cnt == 0) cnt = 1;
k += cnt * t;
x -= cnt;
if(k > 1000000000000){
cout << "-1" << endl;
return ;
}
}
总代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
void solve(){
int x, y, k; cin >> x >> y >> k;
if(y == 1){
cout << "-1" << endl;
return ;
}
while(x > 0){
int t = (k - 1) / (y - 1);
if(t == 0) break;
int cnt = ((t + 1) * (y - 1) - k + t) / t;
cnt = min(cnt, x);
if(cnt == 0) cnt = 1;
k += cnt * t;
x -= cnt;
if(k > 1000000000000){
cout << "-1" << endl;
return ;
}
}
if(k > 1000000000000) cout << "-1" << endl;
else cout << k << endl;
return ;
}
signed main(){
HelloWorld;
int tt = 1;
cin >> tt;
while(tt --) solve();
return 0;
}



京公网安备 11010502036488号