牛客网NOIP赛前集训营-提高组(第四场)

这里是比赛w

A 动态点分治

题目在这里呀~

题意

输出所有 [ l , r ] [l,r] [l,r]范围内能表示为k的若干次的数。
(注意0^0=1)

题解

暴力做…k为2,r为2^63次时最多乘63次所以时间可行。
emmm我特判掉了k=0和1的情况(不知道可不可以不特判?
稍微注意一下细节即可。

//Suplex
#include 
#include 
#include 
#include 
#include 
#define ll long long
using namespace std;
int T;

int main()
{
    scanf("%d",&T);
    while(T--){
        ll l,r,k;
        scanf("%lld%lld%lld",&l,&r,&k);
        if(!k){
            if(l>1){puts("None.");continue;}
            if(l<=0 && r>=0) printf("0 ");
            if(l<=1 && r>=1) printf("1 ");
            puts("");continue;
        }
        if(k==1){
            if(l<=1 && r>=1) puts("1");
            else puts("None.");
            continue;
        }
        ll x=1;
        while(x<l && x<=(ll)r/k) x*=k;
        if(x<l || x>r){puts("None.");continue;}
        printf("%lld",x);
        while(x<=(ll)r/k){x*=k;printf(" %lld",x);}
        puts("");
    }
    return 0;
}

B 区间

题目在这里呀~

题意

求最长的区间长度使得区间内存在一个 a i a_i ai等于这个区间所有数的最大公约数。

题解

一开始并不会做?以及不加读优跑不过去?
暴力思想枚举那个 a i a_i ai然后向两边扩展,更新答案。
那么向右扩展那些是 a i a_i ai倍数的都不会作为最优解,所以枚举的i直接跳到右端点后。这样时间复杂度就是O(n)的啦~
还有别的各种写法比如…单调栈?可是并不懂/youl

//Suplex
#include 
#include 
#include 
#include 
#include 
using namespace std;
int n;long long a[4004000];

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

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) a[i]=read();
    int k=1,ans=1;
    while(k<=n){
        int l=k-1,r=k+1;
        while(a[r]%a[k]==0 && r<=n) r++;
        while(a[l]%a[k]==0 && l>0) l--;
        r--;l++;
        ans=max(ans,r-l+1);
        k=r+1;
    }
    printf("%d\n",ans);
    return 0;
}

C 灭虫

代填。

你可能感兴趣的:(OI)