杭电5288如何查找一个数字的最左边因子和最右边因子的下标,先处理100以下的数字,100以上的数字则是sqrt(n)
2015-07-22 19:24
281 查看
对于区间问题,一般统计满足区间的区间对结果的贡献值为多少,这个题就可以统计每个数字的因子的左右最近的值得下标
l[i],r[i],则这个数字对答案的贡献值为(i-l[i])*(r[i]-i),这个题o(n*n)的算法显然不行,于是看到输入数据为10000从这里下手,
先处理1~100,按照先输入的必在后输入的前面的关系,正向扫描统计l[i],同时反向扫描统计r[i],然后按照ai的倍数关系,
由于现在ai>100且第二层循环是按照ai的倍数递增的,所以总的时间为O(n^sqrt(n)),由于提前储存了每个数出现的下标,
而且先存入的坐标肯定在后存入的前面,所以就按照倍数关系正向扫描,起初的下标必定小于i,所以更新他们的左边因子,
同理反向更新右边因子。
l[i],r[i],则这个数字对答案的贡献值为(i-l[i])*(r[i]-i),这个题o(n*n)的算法显然不行,于是看到输入数据为10000从这里下手,
先处理1~100,按照先输入的必在后输入的前面的关系,正向扫描统计l[i],同时反向扫描统计r[i],然后按照ai的倍数关系,
由于现在ai>100且第二层循环是按照ai的倍数递增的,所以总的时间为O(n^sqrt(n)),由于提前储存了每个数出现的下标,
而且先存入的坐标肯定在后存入的前面,所以就按照倍数关系正向扫描,起初的下标必定小于i,所以更新他们的左边因子,
同理反向更新右边因子。
#include<iostream> #include<cstdio> #include<cstring> #include<cctype> #include<cstdlib> #include<cctype> #include<string> #include<set> #include<map> #include<vector> #include<algorithm> using namespace std; #define LL long long const LL mod=1e9+7; const int N=1e5+10; int a ,p ,l ,r ; vector<int> vec ; int main() { LL n; while(cin>>n) { for(int i=101;i<=10000;i++) vec[i].clear(); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); l[i]=0; r[i]=n+1; if(a[i]>100) vec[a[i]].push_back(i); } for(int j=1;j<=100;j++) { int tem=0; for(int i=1;i<=n;i++) { if(a[i]%j==0) l[i]=max(l[i],tem); if(a[i]==j) tem=i; } tem=n+1; for(int i=n;i>0;i--) { if(a[i]%j==0) r[i]=min(r[i],tem); if(a[i]==j) tem=i; } } memset(p,0,sizeof(p)); for(int i=1;i<=n;i++) { if(a[i]>100) { for(int j=a[i];j<=10000;j+=a[i]) { while(p[j]<vec[j].size()&&vec[j][p[j]]<i) { r[vec[j][p[j]]]=min(r[vec[j][p[j]]],i); if(p[j]<vec[j].size()-1&&(vec[j][p[j]+1]<i)) p[j]++; else break; } } } } for(int i=10000;i>=101;i--) p[i]=vec[i].size()-1; for(int i=n;i>0;i--) { if(a[i]>100) { for(int j=a[i];j<=10000;j+=a[i]) { while(p[j]>=0&&vec[j][p[j]]>i) { l[vec[j][p[j]]]=max(l[vec[j][p[j]]],i); if(p[j]>0&&vec[j][p[j]-1]>i) p[j]--; else break; } } } } LL sum=0; for(int i=1;i<=n;i++) sum=(sum+((i-l[i])*(r[i]-i))%mod)%mod; cout<<sum<<endl; } return 0; }
相关文章推荐
- hdu 5294 Tricks Device 最短路+最大流
- 223 Rectangle Area
- java中request,application,session三个域及参数简单示例
- 类内代码执行顺序
- Xcode中Command Line Tools安装方法
- credit risk 预测建模 - try 2
- android细节问题
- 获取想要格式的时间 simpledateformat
- 普及windows流氓程序和监控软件
- [DLX精确覆盖+打表] hdu 2518 Dominoes
- Introduction to Deep Neural Networks
- 利用matlab如何在图形中绘制箭头
- 三角形
- Table 9-7 -- total_zeros tables for 4x4 blocks with TotalCoeff(coeff_token) 1 to 7
- 嵌入式系统基础知识------之嵌入式系统的硬件基础(1.3)
- hdu 2020绝对值排序
- eclipse / MyEclipse JSP默认打开方式更改
- 字典
- LCA(最近公共祖先) 离线法(tarjan算法)
- [Leetcode] - Jump Game