题目大意
题解
神仙题
直接在原序列上不好搞,考虑按照值顺序考虑,设直接加的为一类数,求和加进去的为二类数
有一个牛比结论:([i(k^2+1)+1,(i+1)(k^2+1)])中存在恰好一个二类数(i从0开始)
先假设这个是对的,当前已知第i段的数为x,考虑求第ki+t段的x',初始段为0目标段为(n-1)/(k^2+1),初始x为k(k+1)/2
(x'=sum_{j=1}^i i(k^2+1)+kt+j+[...>=x])
因为每段长为k^2+1,所以会在后面产生恰好k个二类数,由于不知道前面的二类数所以只考虑本段产生的
展开得到(x'=ik(k^2+1)+k^2t+k(k+1)/2+(0 ext{~}k))
考虑第ki+t段的范围,发现当k>=2时即使后面的0~t是最坏情况也刚好在范围内,所以不展开了(
于是可以算出x',后面的考虑区间与x的关系可以求出
最后根据n和x的大小关系讨论即可O(log)求解
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define ll long long
//#define file
using namespace std;
int a[101],T,i,j,k,l,tot;
ll s,n,K,x,I,ans;
void turn(ll t) {x=I*K*(K*K+1)+K*K*t+(1+K)*K/2+max(I*(K*K+1)+K*t+K-max(x,I*(K*K+1)+K*t+1)+1,0);}
int main()
{
#ifdef file
freopen("CF1242D.in","r",stdin);
#endif
scanf("%d",&T);
for (;T;--T)
{
scanf("%lld%lld",&n,&K),s=(n-1)/(K*K+1);
x=s,tot=0;
while (x) a[++tot]=x%K,x/=K;
I=0,x=K*(K+1)/2;
fd(i,tot,1)
turn(a[i]),I=I*K+a[i];
if (n==x)
ans=(s+1)*(K+1);
else
ans=n-s-(n>=x)+(n-s-(n>=x)-1)/K;
printf("%lld
",ans);
}
fclose(stdin);
fclose(stdout);
return 0;
}