zoukankan      html  css  js  c++  java
  • 【数论,思路】HDU-5288;多校#1-1001

    2015 Multi-University Training Contest 1  1001

     1 /*
     2 Problem: HDU-5288,多校#1 1001
     3 Tips:    数学。思路
     4 Date:    2015.7.29
     5 题意:    给出含n个元素的数组a,问所有区间中,满足对该区间所有aj(j!=i),都使ai%aj!=0的i的个数;
     6 分析:    对于a[i],找到左右两边离它最近的因子的位置lp[i],rp[i],(没有的话就分别设为0/(n+1)),那么a[i]在仅会在(rp[i]-i)*(i-lp[i])个区间内出现
     7 注意:    求lp, rp的算法,小心超时!
     8 */
     9 
    10 
    11 #include<iostream>
    12 #include<cstdio>
    13 #include<cstdlib>
    14 #include<cmath>
    15 #include<vector>
    16 #include<map>
    17 #include<cstring>
    18 using namespace std;
    19 typedef long long ll;
    20 const int maxn = 100010;
    21 const int M = 10010;
    22 const ll MOD = 1000000007;
    23 int n, a[maxn];
    24 
    25 vector<int> fac[M];
    26 int lp[maxn], rp[maxn], pre[M];
    27 void get_fac() //储存1~10000所有数的因子
    28 {
    29     for(int i = 1; i < M; i++)
    30          for(int j = 1; j*j <= i; j++)
    31             if(i % j == 0)
    32             {
    33                 if(j * j != i) fac[i].push_back(i / j);
    34                 fac[i].push_back(j);
    35             }
    36 }
    37 
    38 int main()
    39 {
    40     get_fac();
    41     while(~scanf("%d", &n))
    42     {
    43         for(int i = 1; i <= n; i++)
    44             scanf("%d", &a[i]);
    45 
    46         memset(pre, 0, sizeof(pre));//pre数组记录数字i所在(上一个)位置
    47         for(int i = 1; i <= n; i++) //找左边因子位置
    48         {
    49             int u = a[i], pos = 0;  //pos记录左边最靠近i的因子位置
    50             for(int j = 0; j < fac[u].size(); j++)
    51             {
    52                 int v = fac[u][j];
    53                 pos = max(pos, pre[v]);
    54             }
    55             lp[i] = pos;
    56             pre[u] = i;
    57         }
    58 
    59         memset(pre, 0x3f, sizeof(pre)); //pre数组记录数字i所在(上一个)位置
    60         for(int i = n; i >= 1; i--)     //找右边因子位置
    61         {
    62             int u = a[i], pos = n+1;    //pos记录右边最靠近i的因子位置
    63             for(int j = 0; j < fac[u].size(); j++)
    64             {
    65                 int v = fac[u][j];
    66                 pos = min(pos, pre[v]);
    67             }
    68             rp[i] = pos;
    69             pre[u] = i;
    70         }
    71 
    72         ll res = 0;
    73         for(int i = 1; i <= n; i++)
    74         {
    75             res += (ll)((rp[i]-i) * (i-lp[i])) % MOD;
    76         }
    77         printf("%lld
    ", res % MOD);
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    敏捷转型——团队如何变敏捷?
    什么是敏捷方法论
    禅道项目管理软件会有夜间模式吗?
    程序员如何避免“代码被猫吃了”?
    项目经理:我太难了!
    python进阶(4)--字典
    python进阶(3)--条件判断、用户输入
    python进阶(2)--列表
    python进阶(1)--变量与数据类型、python之禅
    java进阶(42)--注解
  • 原文地址:https://www.cnblogs.com/LLGemini/p/4685561.html
Copyright © 2011-2022 走看看