【HDOJ 5288】OO’s Sequence

【HDOJ 5288】OO’s Sequence

枚举

题目给了个函数f(l,r) 求区间[l,r]有多少个数满足区间内任何一个数都不为他的约数

算出i [1,n] 每个位置的数的最大满足范围 即该位置的数对结果的贡献

两个函数 l[] r[] 存储每个位置的数贡献范围

譬如:

5

4 3 2 1 2 4

五个数的贡献范围分别为

(0,2)

(0,4)

(0,4)

(3,6)

(4,6)

计算区间范围

开一个数组pre[]存放遍历到此时每个数字在之前出现的位置

i(1->n) 每遍历一个数 更新之前出现的该数的倍数的区间右边界

(r[ pre[ num[i] ] ])

i(n->1) 每遍历一个数 更新之前出现的该数的倍数的区间左边界

(l[ pre[ num[i] ] ])

最终结果为i(1->n) (i-l[i])*(r[i]-i) 的累加和对10^9+7取余

代码如下

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#define ll long long
#define mod 1000000007

using namespace std;

int num[100005],l[100005],r[100005],pre[100005];

int main()
{
    int n,j,i,mm;
    ll ans;
    while(~scanf("%d",&n))
    {
        mm = ans = 0;
        memset(pre,0,sizeof(pre));
        for(i = 1; i <= n; ++i)
        {
            scanf("%d",&num[i]);
            mm = max(mm,num[i]);
            l[i] = 0;
            r[i] = n+1;
            for(j = num[i]; j <= mm; j += num[i])//找倍数时用了一个最大值变量mm进行剪枝 速度快很多 后面找左边界时同理
                if(pre[j] && r[pre[j]] > i) r[pre[j]] = i;
            pre[num[i]] = i;
        }
        memset(pre,0,sizeof(pre));
        mm = 0;
        for(i = n; i >= 1; --i)
        {
            mm = max(mm,num[i]);
            for(j = num[i]; j <= mm; j += num[i])
                if(pre[j] && l[pre[j]] < i) l[pre[j]] = i;
            pre[num[i]] = i;
        }
        for(i = 1; i <= n; ++i)
        {
            ans = (ans+((i-l[i])*(r[i]-i))%mod)%mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-01 07:12:54

【HDOJ 5288】OO’s Sequence的相关文章

【BC#24 1002 HDOJ 5273】Dylans loves sequence

[BC#24 1002 HDOJ 5273]Dylans loves sequence 逆序对动归 比赛时候各种奇葩姿势都上了个遍 归并也憋出来了 谁知道就给我看这个.... 赛后有的思路 收到赛后题解的启发 dp[l][r]是l~r之间逆序对 先暴力把dp[1][1~n]枚举出来 然后i从2~n枚举左边界 右边界从i+1~n 这样dp[i][j] 即求出了区间左端点从2往后的所有逆序对数 而dp[i][j]即为dp[i-1][j]中吧i-1的逆序对数减去的余数 这样顺序暴力即可......还是

【HDOJ 4763】 Theme Section (KMP+strstr)

[HDOJ 4763] Theme Section Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1999    Accepted Submission(s): 947 Problem Description It's time for music! A lot of popular musicians a

【HDOJ 4768】 Flyer (等差数列+二分)

[HDOJ 4768] Flyer (等差数列+二分) Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2022    Accepted Submission(s): 743 Problem Description The new semester begins! Different kinds of student soc

【HDOJ 5379】 Mahjong tree

[HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根结点1可以标1或n 否则其他情况无法让下面的子树满足各自连续并且该根的儿子节点都要连续 根结点下的节点平分其他标号 画一画可以发现 每个根下最多有两颗子树 否则无法满足条件 并且两颗子树占据剩余标号的左右两边 中间夹的必须是叶子 这样才能满足该根下的儿子节点标号连续 若根下只有一颗子树 同样可以选择占剩

【HDOJ 5384】Danganronpa

[HDOJ 5384]Danganronpa AC自动机...当时感觉用字典树 标神也往自动机想来着..手太生加上时间紧迫也没敲--回来一看题解什么AB同时建自动机...顿时愣了 什么叫同时建= =问了问财神说普通自动机...B串单建 立马疯了--这不就是模板题么... B串建自动机 A串枚举查询 写完兴冲冲1T--立马想法优化 建fail时压缩一下 查询时直接累计 不再循环找fail 171ms...第二个自动机的题..距上次蛮久了 这次一复习 感觉印象差不多有了 代码(模板)如下: #inc

【LeetCode OJ】Longest Consecutive Sequence

Problem Link: http://oj.leetcode.com/problems/longest-consecutive-sequence/ This problem is a classical problem where we can reduce the running time by the help of hash table. By given a list of numbers, we can find the longest consecutive sequence b

【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)

[HDOJ 5834]Magic boy Bi Luo with his excited tree(树型DP) Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Bi Luo is a magic boy, he also has a migic tree,

【HDOJ 4686】 Arc of Dream (矩阵快速幂)

[HDOJ 4686] Arc of Dream (矩阵快速幂) 两个公式 a(i) = a(i-1)*Ax+Ay b(i) = b(i-1)*Bx+By 求 0~(n-1) 的a(i)*b(i) 初始矩阵为                                       求幂矩阵为 a0                                                      Ax          0           0          0        

【HDOJ 1005】 CRB and His Birthday

[HDOJ 1005] CRB and His Birthday 背包 商场卖东西 没件物品有对应的价值 同时由于超市老板跟你是好绩优...每买一件物品给你a个糖果 同时如果购买某物品 会给对应的b种糖果 即买x个i 可以得到ai*x+bi个糖果 问怎么能得到最多糖果 开始是想开个bool标记每个状态某糖果买每买 还有在该状态是否第一次买某种糖果 写着写着写不好了-- 后来突然想到 可以把每件物品拆开 由于每种物品只赠送一次b 可以把赠b的物品作为"特卖品" 其余为正常送a的物品 这样