hdu 5288 OO’s Sequence 2015 Multi-University Training Contest 1
来源:互联网 发布:单片机交通灯设计步骤 编辑:程序博客网 时间:2024/06/05 07:53
这一题开始想到了枚举却忘了二分><
考虑以下case,如果Left[i]是a[i]左边最近的可以整除的因子,Right[i]是a[i]右边最近的可以整除的因子,那么这个区间就是合法区间,对ans的贡献就是[i-(Left[i]+1)+1]*[(Right[i]-1)-i+1]。
如果在二分搜索中找不到左右边界Left[i]和Right[i],即在[0,n-1]中都没有a[i]的因子,区间对ans的贡献就是[i-Left[i]+1]*[Right[i]-i+1]。这种case对应的边界是Left[i]=0,Right[i]=n-1,所以二分查找的边界应该设为l=-1,r=n。查找失败返回值恰好弥补了这种case里的+1。
另外,分解因子需要预处理,否则会TLE。也许这种O(n)的做法才是正解HDU5288 OO’s Sequence
#include<iostream>#include<stdio.h>#include<cstdio>#include<stdlib.h>#include<vector>#include<string>#include<cstring>#include<cmath>#include<algorithm>#include<stack>#include<queue>#include<ctype.h>#include<map>#include<time.h>#include<bitset>#include<set>#include<list>using namespace std;//hdu 5288const int maxn=100010;const int mod=1e9+7;int a[maxn];int n;int Left[maxn];int Right[maxn];vector<int>loc[maxn];vector<int>fact[maxn];long long ans=0;void calcfact(int x){ for(int j=1;j*j<=x;j++) { if(x%j==0) { fact[x].push_back(j); if(x/j!=j) { fact[x].push_back(x/j); } } }}int findleft(int x,int y){ int l=0; int r=loc[x].size()-1; int mid=(l+r)/2; int ret=-1; while(l<=r) { mid=(l+r)/2; if(loc[x][mid]>=y) { r=mid-1; } else { l=mid+1; if(ret<loc[x][mid]) { ret=loc[x][mid]; } } } return ret;}int findright(int x,int y){ int l=0; int r=loc[x].size()-1; int mid=(l+r)/2; int ret=n; while(l<=r) { mid=(l+r)/2; if(loc[x][mid]<=y) { l=mid+1; } else { r=mid-1; if(ret>loc[x][mid]) { ret=loc[x][mid]; } } } return ret;}int main(){ freopen("input.txt","r",stdin); for(int i=0;i<maxn;i++) { calcfact(i); } while(scanf("%d",&n)!=EOF) { memset(a,0,sizeof(a)); memset(loc,0,sizeof(loc)); memset(Left,0,sizeof(Left)); memset(Right,0x3f,sizeof(Right)); ans=0; for(int i=0;i<n;i++) { scanf("%d",&a[i]); loc[a[i]].push_back(i); Left[i]=-1; Right[i]=n; }// for(int i=0;i<n;i++)//will lead to TLE if we calculated in every test case// {// calcfact(a[i]);// } for(int i=0;i<n;i++) { for(int j=0;j<fact[a[i]].size();j++) { int l=findleft(fact[a[i]][j],i); int r=findright(fact[a[i]][j],i); // cout<<l<<" "<<r<<endl; Left[i]=max(l,Left[i]); Right[i]=min(r,Right[i]); } // cout<<endl; } for(int i=0;i<n;i++) { if((i-Left[i])==0) { ans=(ans+(Right[i]-i)%mod)%mod; } if((Right[i]-i)==0) { ans=(ans+(i-Left[i])%mod)%mod; } else { ans=(ans+(i-Left[i])%mod*(Right[i]-i)%mod)%mod; } } printf("%I64d\n",ans); } return 0;}
0 0
- hdu 5288 OO’s Sequence 2015 Multi-University Training Contest 1
- hdu 5288 OO’s Sequence(2015 Multi-University Training Contest 1)
- hdu 5288 OO’s Sequence 2015 Multi-University Training Contest 1
- HDU 5288 OO’s Sequence (from: 2015 Multi-University Training Contest 1)
- HDU 5288 OO’s Sequence(数学)——2015 Multi-University Training Contest 1
- 2015 Multi-University Training Contest 1 Hdu5288 OO’s Sequence
- 2015 Multi-University Training Contest 1OO’s Sequence hdu5288
- 2015 Multi-University Training Contest 1 OO’s Sequence
- hdu 5289 OO’s Sequence 2015 Multi-University Training Contest 1
- 2015 Multi-University Training Contest 1 Hdu 5297 Y sequence
- 求助2015 Multi-University Training Contest 1_A(hdu 5288)
- hdu 5297 - Y sequence( 2015 Multi-University Training Contest 1)容斥原理
- hdu 4915 Parenthese sequence--2014 Multi-University Training Contest 5
- hdu 6047 Maximum Sequence(2017 Multi-University Training Contest
- hdu 5294 Tricks Device 2015 Multi-University Training Contest 1
- hdu 5289 Assignment 2015 Multi-University Training Contest 1
- 2015 Multi-University Training Contest 1 Hdu 5289 Assignment
- 2015 Multi-University Training Contest 1 Hdu 5292 Pocket Cube
- sdk6下启用spidev
- NSIS nsDialogs Plug-in
- 如何分析Linux日志
- 九度oj 1100
- spring中的任务调度
- hdu 5288 OO’s Sequence 2015 Multi-University Training Contest 1
- Eclipse插件
- sockaddr_in , sockaddr , in_addr区别
- 一个好公司必有的20大铁规定!
- NSIS 下载
- NYOJ 66 分数拆分
- spring事务回滚
- 无法加载 DLL“oramts.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)
- ArrayList的删除