题解 动态点分治

题面

动态点分治

问题描述

CJK 是一个喜欢数据结构的同学。一天他看到 BZOJ 4012 这一题。“这似乎可以用动态点分治做。”,他想。然而他并不会动态点分治,因此他拿着这一题去问 XXX。然而 XXX 跟他说:“你呀,毕竟图样图森破,上台拿衣服!连基础都没学好,就想学这些高端的东西!来,我这里有一题,如果你能把这道题秒掉,我才能教你动态点分治!”于是 CJK 打开题目。题目很短,只有一句话:“给出 l, r, k,请从小到大输出所有在 [l, r] 范围内,能表示为 k 的非负整数次方的所有数。”“多组数据。”,XXX 补充说,“注意所有数的 0 次方都为 1,因此 1 也得算进去哦。”

输入格式

第一行一个数 T,表示数据组数。接下来 T 行,每行 3 个数 l,r,k,表示一组数据。

输出格式

对于每一组数据输出一行(总共输出 T 行)。如果存在符合要求的数,则在一行内从小到大输出这些数;否则输出一个字符串"None."(包括句点,不包括引号)。

输入样例
4
1 10 2
2 4 5
19562 31702689720 17701
3680 37745933600 10

输出样例
1
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==0\)的话就判断下\(0,1\)能否取到,

然后\(k==1\)时就判断下\(1\),

\(k>1\)时暴力乘就行了.

这题就这么完了?

下面总结下一些错误的做法(虽然我没有):

  1. \(k=0/1\)忘记特判.
  2. \(long long\).
  3. 特判的时候输出反了.

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
#define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
using namespace std;

inline int read(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
    return f*sum;
}

const int N=100001;
int T,l,r,k;

signed main(){
//  fre("dynamic");
    T=read();
    while(T--){
        l=read();r=read();k=read();
        int flag=0;
        if(k==0){
            for(int i=0;i<=1;i++) if(i>=l&&i<=r) printf("%lld ",i),flag=1;
        }
        else if(k==1){
            if(1>=l&&1<=r) printf("%d ",1),flag=1;
        }
        else{
            for(int i=1;i<=r;i*=k){
                if(i>=l&&i<=r) printf("%lld ",i),flag=1;
                if(i>r/k) break;
            }
        }
        puts(flag? "":"None.");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zsq259/p/11565029.html