2021年广东工业大学第十五届文远知行杯程序设计竞赛 E 捡贝壳 (分块 | 思维)

E 捡贝壳

https://ac.nowcoder.com/acm/contest/13504/E

E 捡贝壳 (分块 | 思维)

图片说明
图片说明
图片说明

方法一:分块

1.块的大小时根号n,预处理分块数组
2.求解时,对于两边的l,r所在的块不论是否是整块都单独求,先求l所在的,求完后判l,r是否在一个块内(对于是否在一个块内,数组下标从0开始,这样的话数组下标/根号n所得的数字即是第几个块),是则可直接return
3.整块的

#include <bits/stdc++.h>

using namespace std;

int n, m;
int ar[100050];
int sum[320][100050];
int l, r, x, d;

void fenkuai()
{
    d = sqrt(n);
    for(int i = 0; i < n; ++i)
    {
        for(int j = 1; j * j <= ar[i]; ++j)
        {
            if(ar[i] % j == 0)
            {
                sum[i / d][j]++;
                if(ar[i] / j != j)  sum[i / d][ar[i] / j]++;
            }
        }
    }
}

int solve(int l, int r, int x)
{
    //cout << d << endl;
    int ans = 0;
    for(int i = l; i <= r && i / d == l / d; ++i) if(ar[i] % x == 0)    ans++;
    if(l / d == r / d)  return ans;
    for(int i = r / d * d; i <= r ; ++i)   if(ar[i] % x == 0)  ans++;
    for(int i = l / d + 1; i <= r / d - 1; ++i) ans += sum[i][x];
    return ans;
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; ++i) scanf("%d", &ar[i]);
    fenkuai();
    for(int i = 1; i <= m; ++i)
    {
        scanf("%d%d%d", &l, &r, &x);
        --l, --r;
        int ans = solve(l, r, x);
        printf("%d\n", ans);
    }
    return 0;
}

方法二:思维(vector + 二分查找)

分析:
据数据范围1e5,需要找x的倍数,我们可以枚举所有x的倍数,即2x,3x,...,一直到1e5(1e5不是1e9,可以枚举),我们需要判是否存在这些数,以及这些数是否在要求的区间内,很明显可以用一个容器来存每个数出现的位置。而这个容器肯定就是vector惹
(时间复杂度,空间复杂度都比分块优)
AC代码:

#include <bits/stdc++.h>

using namespace std;

int n, m;
int l, r, x;
int a, ans;
vector<int> vt[1000050];

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d", &a);
        vt[a].push_back(i);
    }
    while(m--)
    {
        scanf("%d%d%d", &l, &r, &x);
        ans = 0;
        for(int i = x; i <= 100000; i += x) ans += upper_bound(vt[i].begin(), vt[i].end(), r) - lower_bound(vt[i].begin(), vt[i].end(), l);
        printf("%d\n", ans);
    }
    return 0;
}
全部评论
大佬,如果每次查询的x是1,会不会超时啊
点赞 回复 分享
发布于 2021-11-19 19:17

相关推荐

08-01 11:19
电气工程师
点赞 评论 收藏
分享
07-11 22:27
中南大学 Java
程序员牛肉:学历的话没问题。但是没问题的也就只有学历了。 其实你的整体架构是正确的,博客接着干。但是项目有点过于简单了。从后端的角度上讲,你这也就是刚入门的水平,所以肯定约面试够呛。 如果你要应聘后端岗位,那你第一个项目竟然是仿写操作系统。这个你要面试官咋问你。你一定要记住一点,你简历上写的所有的东西,都是为了证明你有能力胜任当前的岗位,而不是为了证明你自己会什么。 如果你只是浅浅的做几个项目,描述也都是烂大街。技术点也都是各种混水类的配置类需求,那你就不要幻想自己能走多远。一定要保持思考,保持学习。
点赞 评论 收藏
分享
评论
6
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务