HDU 5288 OO’s Sequence

分析:题意是给你n个数字,全部区间[i,j](1<=i<=n,i<=j<=n)内满足一个数与区间中的其他数互质的数有多少个。定义两个一维数组l,r,l[i]和r[i]表示第i个数左侧和右侧最接近a[i]的且是a[i]的因子的数的位置,那么a[i]在区间(x,y)(l[i]<x<=i,i<=y<r[i])内均满足和区间内的其他元素互质,所以a[i]能贡献的答案是(i-l[i])*(r[i]-i)。

# include <stdio.h>
# include <string.h>
# define mod 1000000007
# define MAX(x,y) ((x)>(y))?(x):(y)
# define MIN(x,y) ((x)<(y))?(x):(y)
  int a[100005],l[100005],r[100005],mark[100005];
  int main()
  {
      int i,j,n,tmp;
      __int64 a1,a2,sum;
      while(scanf("%d",&n)!=EOF)
      {
          for(i=1;i<=n;i++)
          {
              l[i]=0;
              r[i]=n+1;
              scanf("%d",&a[i]);
          }
          memset(mark,0,sizeof(mark));
          for(i=1;i<=n;i++)//a[1]~a[n]寻找a[i]的l[i]值,
          {
              for(j=1;j*j<=a[i];j++)//枚举a[i]的因子
              {
                  if(a[i]%j)
                    continue;
                  if(mark[j])//j为a[i]的因子,判断a[i]的左侧有没有j
                    l[i]=MAX(l[i],mark[j]);
                  if(mark[a[i]/j])//同样a[i]/j也为a[i]的因子
                    l[i]=MAX(l[i],mark[a[i]/j]);
              }
              mark[a[i]]=i;//每次查找完标记a[i]的位置
          }
          memset(mark,0,sizeof(mark));
          for(i=n;i>=1;i--)//查找r[i]
          {
              for(j=1;j*j<=a[i];j++)
              {
                  if(a[i]%j)
                    continue;
                  if(mark[j])
                    r[i]=MIN(r[i],mark[j]);
                  if(mark[a[i]/j])
                    r[i]=MIN(r[i],mark[a[i]/j]);
              }
              mark[a[i]]=i;
          }
          for(i=1,sum=0;i<=n;i++)
          {
              a1=i-l[i];
              a2=r[i]-i;
              sum=(sum+a1*a2)%mod;
          }
         printf("%I64d\n",sum);
      }
      return 0;
  }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值