hdu 5288OO’s Sequence

来源:互联网 发布:淘宝60s视频制作软件 编辑:程序博客网 时间:2024/04/29 23:53

给你n个数,让你找到所有区间内不能整除其它数的数的个数之和
之前的代码正确是因为数据比较水

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int mod = 1e9+7;#define ll long long#define N 111111int l[N],r[N];//存储左边因子。右边因子的位置int n,m;int pre[N],last[N];int a[N];vector<int>g[N];int main() {    while(scanf("%d",&n)==1) {        for (int i=101;i<=10000;i++)        g[i].clear();        for(int i=1; i<=n; i++) {            scanf("%d",&a[i]);            if(a[i]>100)            g[a[i]].push_back(i);            l[i]=0;            r[i]=n+1;//初始化最左边的因子和最右边的因子都是本身        }        memset(pre,0,sizeof(pre));        memset(last,0,sizeof(last));        int  tmp;        for (int j=1; j<=100; j++) {            tmp=0;            for (int i=1; i<=n; i++) {                if (a[i]%j==0) l[i]=max(l[i],tmp);                if (a[i]==j)                    tmp=i;            }            tmp=n+1;            for (int i=n; i>=1; i--) {                if (a[i]%j==0) r[i]=min(r[i],tmp);                if (a[i]==j)                    tmp=i;            }        }        for (int i=101; i<=10000; i++)            pre[i]=0;//r数组从小到大寻找位置        for (int i=1; i<=n; i++)            if (a[i]>100) {                for (int j=a[i]; j<=10000; j=j+a[i])                    while ((pre[j]<g[j].size())&&(g[j][pre[j]]<i)) //当下标小于i的时候,这个下标所存在数的右因子才可能是i                    {                        r[g[j][pre[j]]]=min(r[g[j][pre[j]]],i);                        if ((pre[j]<g[j].size()-1)&&(g[j][pre[j]+1]<i))//如果成功找到了,那么继续向下找过去                            pre[j]++;                        else                            break;                    }            }        for (int i=101; i<=10000; i++)            last[i]=g[i].size()-1;//l数组从大到小寻找位置        for (int i=n; i>=1; i--)            if (a[i]>100) {                for (int j=a[i]; j<=10000; j=j+a[i])                    while ((last[j]>=0)&&(g[j][last[j]]>i)) {                        l[g[j][last[j]]]=max(l[g[j][last[j]]],i);                        if ((last[j]>0)&&(g[j][last[j]-1]>i))                            last[j]--;                        else                            break;                    }            }        /*        for(int i=1;i<=n;i++){            printf("%d %d %d\n",i,l[i],r[i]);        }         */        ll ans = 0;        for(int i=1; i<=n; i++) {            ans = (ans%mod+(ll)(i-l[i])*(r[i]-i)%mod)%mod;        }        printf("%I64d\n",ans);    }}
0 0
原创粉丝点击