nowcoder(牛客网)提高组模拟赛第四场 解题报告

T1 动态点分治



就是模拟。。。。。

但是没有过!!

看了题解之后发现。。。。

坑点:有可能 \(x<=r\),但是 𝑘𝑥 溢出了,溢出之后刚好又在 𝑙,𝑟 甚至 𝑥,𝑟 之间

应对措施:如果\(x>r\),就\(break\)

以下是代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
inline long long read()
{
	long long f=1,x=0; char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
int t;
long long l,r,k;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		l=read(),r=read(),k=read();
		if(k==0) 
		{
			if(l>1)
			{
				printf("None.\n");
				continue;
			}
			if(l<=0) printf("0 ");
			if(l<=1&&r>=1) printf("1 ");
			printf("\n");
			continue;
		}
		else if(k==1)
		{
			if(l<=1&&r>=1) printf("1\n");
            else
			{
				printf("None.\n"); 
				continue;
			}
			continue;
		}
		else
		{
			long long cur=1;
			while(cur<=((long long)r/k)&&cur<l) cur*=k;
			if(cur<l||cur>r)
			{
				printf("None.\n");
				continue;
			}
			printf("%lld",cur);
			while(cur<=(long long)r/k) cur*=k,printf(" %lld",cur);
			printf("\n");
		}
	}
	return 0;
 } 

T2 区间



如果是最大公约数的话。。。

那必须是区间里面最小的数。

可以考虑枚举每个数,然后向左向右拓展。当然可以优化时间复杂度,显然可得如果访问过的点就不用再访问一遍了。

90分:时间复杂度\(O(nlogn)\)

90分代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstdlib>
#define MAXN 20000010
using namespace std;
int n,ans;
int done[MAXN];
long long a[MAXN];
inline long long read()
{
    long long f=1,x=0; char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
int main()
{
     
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        a[i]=read();
    for(int i=1;i<=n;i++)
    {
        int cur=1;
        if(done[i]==1) continue;
        done[i]=1;
        for(int j=i-1;j>=1;j--)
        {
            if(a[j]%a[i]==0)cur++,done[j]=1;
            else break;
        }
        for(int j=i+1;j<=n;j++)
        {
            if(a[j]%a[i]==0)cur++,done[j]=1;
            else break;
        }
        ans=max(ans,cur);
    }
    printf("%d\n",ans);
 
    return 0;
}

但是还可以更快。。。。

还是每次拓展,以\(r\)为例,我们可以注意到假如说\(r[i]<r[i-1]\),那么这个肯定是没有贡献的。拓展出来的\(r[i]\)不一定单调,但是因为如果小的话是没有贡献的,所以我们可以把\(r[i]\)当作一个中间量,强制进行单调性来推。

捞一个代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int wx=4000017; 
long long a[wx];
int l[wx],r[wx];
int n;
int ans;
inline long long read()
{
	long long f=1,x=0; char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
		a[i]=read();
    for(int i=1;i<=n;i++)
		for(l[i]=i;l[i]>1&&a[l[i]-1]%a[i]==0;l[i]=l[l[i]-1]);
    for(int i=n;i>=1;i--)
		for(r[i]=i;r[i]<n&&a[r[i]+1]%a[i]==0;r[i]=r[r[i]+1]);
    for(int i=1;i<=n;i++)
		ans=max(ans,r[i]-l[i]+1);
    printf("%d\n",ans);
    return 0;
}

T3 灭虫



CF559E
不会做
看了题解也不会
听了讲评也不会
蒻死了

posted @ 2018-11-01 20:27  风浔凌  阅读(154)  评论(0编辑  收藏  举报