hdu 5288 OO’s Sequence 2015 Multi-University Training Contest 1

OO’s Sequence

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 83    Accepted Submission(s): 34


Problem Description
OO has got a array A of size n ,defined a function f(l,r) represent the number of i (l<=i<=r) , that there's no j(l<=j<=r,j<>i) satisfy a i mod a j=0,now OO want to know
i=1nj=inf(i,j) mod 109+7.

 

Input
There are multiple test cases. Please process till EOF.
In each test case: 
First line: an integer n(n<=10^5) indicating the size of array
Second line:contain n numbers a i(0<a i<=10000)
 

Output
For each tests: ouput a line contain a number ans.
 

Sample Input
   
   
   
   
5 1 2 3 4 5
 

Sample Output
   
   
   
   
23
 

Source
2015 Multi-University Training Contest 1



求一个每个区间中,满足其他数字%该数字 != 0的数字个数,把每个区间满足条件的个数相加

方法:

枚举每个位置,求包含这个数字的区间个数,做加法。

对于ai,看ai左边最近的位置l,al是ai的因数,右边位置r,ar是ai的因数。那么满足的个数就是

(i-l)*(r-i)

预处理所有1-10000的因数。

从左到右,用pre[i]表示数字i出现的i的最右边的位置。算出每个位置的l。

同理从右到左,算出每个位置的r。







#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;


#define maxn 100007
vector<int> head[10007];
int pre[10007];
int num[maxn];

int lef[maxn];
int righ[maxn];

int main(){
    int n;
    for(int i = 1;i <= 10000;i++){
        head[i].clear();
        for(int j = 1;j*j<=i;j++){
            if(i%j == 0){
                head[i].push_back(j);
                head[i].push_back(i/j);
            }
        }
    }
    while(scanf("%d",&n)!=EOF){
        for(int i = 1;i <= n; i++)
            scanf("%d",&num[i]);
        memset(pre,0,sizeof(pre));
        for(int i = 1;i <= n; i++){
            int u = num[i];
            int p = 0;
            for(int j = 0;j < head[u].size(); j++)
                p = max(p,pre[head[u][j]]);
            lef[i] = p;
            pre[u] = i;
        }

        memset(pre,0x3f,sizeof(pre));
        for(int i = n; i > 0; i--){
            int u = num[i];
            int p = n+1;
            for(int j = 0;j < head[u].size();j++)
                p = min(p,pre[head[u][j]]);
            righ[i] = p;
            pre[u] = i;
        }
        long long ans = 0,l,r;
        long long mod = 1000000007;
        for(int i = 1; i <= n; i++){
            ans += (long long)(i-lef[i])*(righ[i]-i);
            ans %= mod;
        }
        cout<<ans<<endl;
    }
    return 0;
}









你可能感兴趣的:(HDU,多校联合训练赛)