专栏文章
[CF2169D2] Removal of a Sequence (Hard Version) 题解
CF2169D2题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min189sp
- 此快照首次捕获于
- 2025/12/01 18:54 3 个月前
- 此快照最后确认于
- 2025/12/01 18:54 3 个月前
每次操作都将位置为 的数移动到位置 ,注意到 值唯一,可以考虑求出其反函数 ,然后尝试计算 ( 表示 ,其中 有 层)。
如何直观地推出 ?考虑 的过程,将 划分为若干段,每一段长度为 ,然后删去每一段的末尾(需要满足 ,于是最后一段不足 ,不作操作),此时 移动到的位置即为 。反过来,可以看作 划分为若干个长为 的段,每一段都在末尾加上一个点(最后一段除外),可以发现实际上加上了 个点,于是我们得到 ,即 。
接下来考虑如何求 ,注意到 实际上有很多时候相同,可以考虑将这些相同的增量都压缩在一起。下面先证明这样做的复杂度是正确的:显然每次求出的增量都至少增加 ,则情况不弱于使得 的最小的 ,而 ,于是至多需要求出 次增量。
接下来计算增量的边界,设当前增量为 ,则使得 的最大的 为 ,于是跳 次后会跳出边界。
时间复杂度 。
code
CPP#include<bits/stdc++.h>
#define pb emplace_back
#define pob pop_back
#define mp make_pair
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
const ll maxn=507,ee=1e18,p=998244353;
ll x,y,k;
ll solve(void){
ll cur=k,stp,tot=0,val;
if(k<y) return k;
if(y==1) return -1;
for(;;){
val=(cur-1)/(y-1);
stp=min(x-tot,((val+1)*(y-1)-cur)/val+1);
cur+=val*stp,tot+=stp;
if(cur>1e12) return -1;
if(tot==x) break;
}
return cur;
}
int main(void){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
ll T=1; cin>>T;
for(;T--;){
cin>>x>>y>>k;
cout<<solve()<<"\n";
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...