题目描述
CJK 是一个喜欢数据结构的同学。一天他看到 BZOJ 4012 这一题。“这似乎可以用动态点分治做。”,他想。然而他并不会动态点分治,因此他拿着这一题去问 XXX。 然而 XXX 跟他说:“你呀,毕竟图样图森破,上台拿衣服!连基础都没学好,就想学这些高端的东西!来,我这里有一题,如果你能把这道题秒掉,我才能教你动态点分治!” 于是 CJK 打开题目。题目很短,只有一句话: “给出 l, r, k,请从小到大输出所有在 [l, r] 范围内,能表示为 k 的非负整数次方的所有数。” “多组数据。”,XXX 补充说,“注意所有数的 0 次方都为 1,因此 1 也得算进去哦。”
输入描述:
第一行一个数 T,表示数据组数。接下来 T 行,每行 3 个数 l,r,k,表示一组数据。
输出描述:
对于每一组数据输出一行(总共输出 T 行)。如果存在符合要求的数,则在一行内从小到大输出这些数;否则输出一个字符串 “None.”(包括句点,不包括引号)。
示例1
输入
4
1 10 2
2 4 5
19562 31702689720 17701
3680 37745933600 10
输出
1 2 4 8
None.
313325401
10000 100000 1000000 10000000 100000000 1000000000 10000000000
备注:
对于所有数据,T ≤ 10000,l ≤ r,0≤ l,r,k < 263。子任务 1(20 分):r - l ≤ 1000。子任务 2(30 分):l, r, k < 231。子任务 3(50 分):l, r, k < 263。这里的子任务表示的是数据类型,并不捆绑测试。三个子任务中,各有 10 分的数据,满足 T = 10 且数据是随机的。特别注意:本题中 0 的 0 次方也看做 1。
思路:
求出现在[ ?,? ]内的形如
k
i
k^i
ki 的数
模拟题意就好了,注意一下 ? = 1 或 ? = 0 的边界
坑点:有可能 ? ≤ ?,但是 ?? 溢出了,溢出之后刚好又在[ ?,? ]甚至[ ?,? ]之间应对措施:如果 ? >
r
k
\frac{r}{k}
kr,则 break
代码:
#include<bits/stdc++.h>
#define int __int128
inline int read()
{
int res=0;
char ch;
while((ch=getchar())<'0'||ch>'9');
for(;ch>='0'&&ch<='9';ch=getchar())
res=res*10+ch-'0';
return res;
}
inline void write(int x)
{
if(x>=10)
write(x/10);
putchar(x%10+'0');
return;
}
inline void solve()
{
int l,r,k;
bool flag=0;
register int i;
l=read();r=read();k=read();
if(k==0)
{
if(l<=0&&r>=0)
putchar('0'),putchar(' '),flag=1;
if(l<=1&&r>=1)
putchar('1'),putchar(' '),flag=1;
if(!flag)
puts("None.");
else
putchar('\n');
return;
}
if(k==1)
{
if(l<=1&&r>=1)
putchar('1'),putchar(' '),flag=1;
if(!flag)
puts("None.");
else
putchar('\n');
return;
}
for(i=1;i<=r;i*=k)
if(i>=l)
write(i),putchar(' '),flag=1;
if(!flag)
puts("None.");
else
putchar('\n');
return;
}
signed main()
{
int T;
T=read();
while(T--)
solve();
return 0;
}
来源:nkw