某次模拟赛 数字对


题目描述 Description


小 H 是个善于思考的学生,现在她又在思考一个有关序列的问题。
她的面前浮现出一个长度为 n 的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n)。这个特殊区间满足,存在一个 k(L <= k <= R),并且对于任意的 i(L <= i <= R),ai 都能被 ak 整除。这样的一个特殊区间 [L, R]价值为 R - L。
小 H 想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢?这些区间又分别是哪些呢?你能帮助她吧。


输入描述 Input Description


第一行,一个整数 n.
第二行,n 个整数,代表 ai.


输出描述 Output Description


第一行两个整数,num 和 val,表示价值最大的特殊区间的个数以及最大价值。
第二行 num 个整数,按升序输出每个价值最大的特殊区间的 L.


样例输入 Sample Input


5
4 6 9 3 6


样例输出 Sample Output


1 3
2


数据范围及提示 Data Size & Hint


30%: 1 <= n <= 30 , 1 <= ai <= 32.
60%: 1 <= n <= 3000 , 1 <= ai <= 1024.
80%: 1 <= n <= 300000 , 1 <= ai <= 1048576.
100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.

之前的一些废话:暑假作业发现还有论语视频没有看,十分慌张

题解:传说中的暴力踩标程。

解法1:先说正解吧,首先最大价值是可以进行二分的,如何判断解是否可行呢?当前解是mid,枚举每一个长度为mid+1的区间,判这个区间是否合法,如果合法就把该区间左端放入队列中,最后检查队列中是否有元素即可(即有没有符合的区间)至于如何判区间是否合法,根据题意只要区间最小值与区间GCD相等就可以,这个可以通过RMQ来处理,O(n log n)预处理,O(1)查询,至于区间GCD通过类似的方法处理即可。    总复杂度O(n log n*log n)

解法2:再说暴力。对于序列中每一个元素进行考虑,假定当前数为ak,那么我们需要计算出ak所属于的最长区间。向左向右分别扫,如果碰到一个数不能整除ak就停,最后计算出该区间长度[L,R]。然后还有一个优化,处理完第i个数后,我们没有必要继续处理第i+1个数,而是直接从第I个数所对应的R的下一个数开始处理即可,因为我们可以证明,从第i+1个数到第R个数中选它们做ak的答案显然没有拿第i个数当ak更优。复杂度O(♂)

解法3:还有一种类似暴力的做法,该做法与暴力做法的区别就是ak不用往左往右扫了,而是通过二分来确定区间长度,不过也需要区间GCD预处理。复杂度O(n log n*log n)

最后实测结果是解法2速度最快 ,解法1第二 解法3第三

代码:

解法1&&解法2的:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define mem(a,b) memset(a,b,sizeof(a))
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c==‘-‘)f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
const int maxn=500010,MAXlog=20;
int n,a[maxn],f[maxn],ans,cnt,Min[MAXlog][maxn],GCD[MAXlog][maxn],len[maxn],L,R,A[maxn],l;
bool ok;
int gcd(int a,int b){return b==0 ? a : gcd(b,a%b);}
int MINquery(int L,int R)
{
    int bin=len[R-L+1];
    return min(Min[bin][L],Min[bin][R-(1<<bin)+1]);
}
int GCDquery(int L,int R)
{
    int bin=len[R-L+1];
    return gcd(GCD[bin][L],GCD[bin][R-(1<<bin)+1]);
}
bool check(int index)
{
    l=0;
    for(int i=1;i+index-1<=n;i++)if(GCDquery(i,i+index-1)==MINquery(i,i+index-1))A[l++]=i;
    if(l)ans=max(ans,index);
    return l;
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)Min[0][i]=GCD[0][i]=a[i]=read();
    for(int i=1;(1<<i)<=n;i++)
        for(int j=1;j+(1<<(i-1))<=n;j++)
        {
            Min[i][j]=min(Min[i-1][j],Min[i-1][j+(1<<(i-1))]);
            GCD[i][j]=gcd(GCD[i-1][j],GCD[i-1][j+(1<<(i-1))]);
        }
    for(int i=2;i<=n;i++)len[i]=len[i>>1]+1;
    L=1;R=n;
    while(R-L>1)
    {
        int mid=(L+R)>>1;
        if(check(mid))L=mid;
        else R=mid;
    }
    check(L);check(R);check(ans);
    printf("%d %d\n",l,ans-1);
    for(int i=0;i<l;i++)
    {
        if(!ok)printf("%d",A[i]),ok=1;
        else printf(" %d",A[i]);
    }
    printf("\n");
    return 0;
}

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define mem(a,b) memset(a,b,sizeof(a))
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c==‘-‘)f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
const int maxn=500010;
int n,a[maxn],f[maxn],ans,cnt;
bool ok;
int gcd(int a,int b){return b==0 ? a : gcd(b,a%b);}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=n;i++)
    {
        int L=i,R=i;
        for(L=i;L>0;L--)if(a[L]%a[i]!=0)break;
        for(R=i;R<=n;R++)if(a[R]%a[i]!=0)break;
        L++;R--;
        f[L]=R-L;
        i=R;
    }
    for(int i=1;i<=n;i++)ans=max(ans,f[i]);
    for(int i=1;i<=n;i++)if(f[i]==ans)cnt++;
    printf("%d %d\n",cnt,ans);
    for(int i=1;i<=n;i++)
        if(f[i]==ans)
        {
            if(!ok)printf("%d",i),ok=1;
            else printf(" %d",i);
        }
    printf("\n");
    return 0;
}

解法3懒得写了。

总结:

时间: 2024-10-27 13:34:27

某次模拟赛 数字对的相关文章

【题解】PAT团体程序设计天梯赛 - 模拟赛

由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz 总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~ L1-1 N个数求和 设计一个分数类,重载加法运算符,注意要约分,用欧几里得算法求个最大公约数即可. 1 #include <cstdio> 2 3 long long abs(long long x) 4 { 5 return x < 0 ? -x : x; 6 } 7 8 long long gcd(long

[铁一中OI模拟赛]2017.8.19 Day1

T1 小Z的情书 题目链接 思考: 题目主要难度在于旋转后的位置如何,在手写了样例之后不难发现规律. #include <cstdio> #include <cstring> #define up(a,b,c) for(register int c=a;c<=b;++c) #define down(a,b,c) for(register int c=a;c>=b;--c) const int Maxn=1005; int n; bool Map[Maxn][Maxn],

2014-11-2 NOIP模拟赛1

Noip2009 团结模拟赛如题目理解困难,请自行阅读或参考样例.内存限制均为 256MB,时间限制均为 1s.出题人不会 故意 在题目中设置陷阱,但请自己注意程序的正确性.IO 文件名(.in/.out)与程序名(题目名)相同.对于所有语言均不使用优化选项.对于 Pascal 选手,打开-Ct –Cr –Ci –Co 四个编译开关.祝各位答题顺利,谢谢. LazyChild 黑 OJ (blackoj.pas/c/cpp) LazyChild 开了一家“善良 OJ” .但大多数人都不知道,这其

9.2模拟赛

cogs 比赛名称 树立信心的模拟赛 T1 2739. 凯伦和咖啡 时间限制:1 s   内存限制:512 MB [题目描述] 为了在上课时保持清醒,凯伦需要一些咖啡.咖啡爱好者凯伦想知道最佳的温度来冲煮完美的咖啡.因此,她花了一些时间阅读几本食谱,其中包括广受好评的"咖啡的艺术". 她知道有n个食谱,其中第i个食谱建议应当在li和ri度之间冲煮以达到最佳的味道.凯伦认为如果至少k个食谱推荐某个温度,那么那个温度是可以接受的. 凯伦的性格比较多变,因此她会问q个问题,对于每一个问题,她

2018 蓝桥杯省赛 B 组模拟赛(一)

2018 蓝桥杯省赛 B 组模拟赛(一) A.今天蒜头君带着花椰妹和朋友们一起聚会,当朋友们问起年龄的时候,蒜头君打了一个哑谜(毕竟年龄是女孩子的隐私)说:“我的年龄是花椰妹年龄个位数和十位数之和的二倍”. 花椰妹看大家一脸懵逼,就知道大家也不知道蒜头君的年龄,便连忙补充道:“我的年龄是蒜头君个位数和十位数之和的三倍”. 请你计算:蒜头君和花椰妹年龄一共有多少种可能情况? 提醒:两位的年龄都是在 [10,100)[10,100) 这个区间内. 题解: 暴力枚举 answer: 1 代码如下: #

20180520模拟赛T3——chess

[问题描述] 小美很喜欢下象棋. 而且她特别喜欢象棋中的马. 她觉得马的跳跃方式很独特.(以日字格的方式跳跃) 小芳给了小美一张很大的棋盘,这个棋盘是一个无穷的笛卡尔坐标. 一开始\(time=0\)的时候,马在原点.每个时刻马都跳一步. 可是这个坐标图有点残缺,有几个点是不能跳到的. 然后小美很好奇在\(time=[0,K]\)中,马能跳到多少个不同的格子. [输入格式] 从文件chess.in中读入数据. 第一行两个数K,n表示时间上限和残缺的点的数量. 接下来n行,每行一个坐标 xi,yi

10-4国庆节第七场模拟赛题解

10-4 国庆节第七场模拟赛题解 T1工厂 (factory) 水 #include<iostream> #include<cstdio> #define int long long using namespace std; inline int read(){ int sum=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); } while(ch>='0

校内模拟赛 Zbq&#39;s Music Challenge

Zbq's Music Challenge 题意: 一个长度为n的序列,每个位置可能是1或者0,1的概率是$p_i$.对于一个序列$S$,它的得分是 $$BasicScore=A\times \sum_{i=1}^{n}{S_i} \tag{1}$$ $$ combo(i)=\left\{ \begin{aligned} &S_i & &i=1 \\ &combo(i-1)+1 & &i\neq 1 ~\mathrm{and}~ S_i=1 \\ &

2019模拟赛09场解题报告

目录 2019模拟赛09场解题报告 目录la~~ 题一:瞬间移动 题二:食物订购 题三:马蹄印 题四:景观美化 2019模拟赛09场解题报告 标签(空格分隔): 解题报告 Forever_chen 2019.8.20 目录la~~ 题一:瞬间移动 [题面] 有一天,暮光闪闪突然对如何将一个整数序列a1,a2,...,an排序为一个不下降序列起了兴趣.身为一只年轻独角兽的她,只能进行一种叫做"单元转换"(unit shift)的操作.换句话说,她可以将序列的最后一个元素移动到它的起始位置