HDU 4777 Rabbit Kingdom 解题报告
来源:互联网 发布:iphone软件授权 编辑:程序博客网 时间:2024/06/05 19:00
题目
题意:
有n个数字,m个查询,每次询问[l,r]这些数字中,和其他数都互质的数有多少个。
题解:
从左到右遍历,对每个数因子分解,如果它含有的因子在之前也有数含有,那么便可知那个数和它不互质,所以可以求出每个数i左边第一个和它不互质的数的位置,记为lefi,右边同理,记为rigi。
然后将查询按l排序,从左往右遍历原数组,遍历到j时,若存在i使得j-1=lefi,则可知从j到(rigi)-1都和i互质,因此如果有查询的l=j,而r=[i,rigi)的话,这个区间里i是一个满足要求的数。这里可以用线段树或者树状数组。
代码:
//Time:1843ms//Memory:9216KB//Length:2574B#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MP(x,y) make_pair(x,y)#define FI first#define SE secondconst int MAXN = 200010;int tree[MAXN];int pri[MAXN],ptop,yin[MAXN];int arr[MAXN],pre[MAXN],ans[MAXN],bel[MAXN];pair<int,int> pa[MAXN];bool vi[MAXN];struct _query{ int l,r,id; bool operator < (const _query &b) const { return l<b.l; }}que[MAXN];void cal(int n){ memset(yin,-1,sizeof(yin)); for(int i=0;i<n;++i) { int pos=-1,tmp=arr[i]; for(int j=0;(long long)pri[j]*pri[j]<=tmp;++j) if(tmp%pri[j]==0) { pos=max(pos,yin[j]); yin[j]=i; while(tmp%pri[j]==0) tmp/=pri[j]; } if(tmp>1) { pos=max(pos,yin[bel[tmp]]); yin[bel[tmp]]=i; } pre[i]=pos+1; }}void add(int h,int num){ ++h; while(h<MAXN) { tree[h]+=num; h+=h&(-h); }}int query(int h){ ++h; int cnt=0; while(h) { cnt+=tree[h]; h-=h&(-h); } return cnt;}int main(){ //freopen("/home/moor/Code/input","r",stdin); int n,m,ql,pl; ptop=0; memset(vi,0,sizeof(vi)); for(int i=2;i<MAXN;++i) if(!vi[i]) { bel[i]=ptop; pri[ptop++]=i; for(int j=i;j<MAXN;j+=i) vi[j]=1; } while(scanf("%d%d",&n,&m)==2&&n) { for(int i=0;i<n;++i) scanf("%d",&arr[i]); cal(n); for(int i=0;i<n;++i) pa[i]=MP(pre[i],i); sort(pa,pa+n); for(int i=0,j=n-1;i<j;++i,--j) swap(arr[i],arr[j]); cal(n); for(int i=0;i<n;++i) pre[i]=n-1-pre[i]; for(int i=0,j=n-1;i<j;++i,--j) swap(arr[i],arr[j]),swap(pre[i],pre[j]); for(int i=0;i<m;++i) scanf("%d%d",&que[i].l,&que[i].r),que[i].id=i,--que[i].l,--que[i].r; sort(que,que+m); ql=0,pl=0; memset(tree,0,sizeof(tree)); for(int i=0;i<n;++i) { if(i) { add(pre[i-1]+1,1); add(i-1,-1); } while(pl<n&&pa[pl].FI==i) { add(pa[pl].SE,1); add(pre[pa[pl].SE]+1,-1); ++pl; } while(ql<m&&que[ql].l==i) { ans[que[ql].id]=query(que[ql].r); ++ql; } } for(int i=0;i<m;++i) printf("%d\n",ans[i]); } return 0;}
- HDU 4777 Rabbit Kingdom 解题报告
- hdu 4777 Rabbit Kingdom
- hdu 4777 Rabbit Kingdom
- HDU 4777 Rabbit Kingdom
- hdu 4777 Rabbit Kingdom
- HDU-4777 Rabbit Kingdom
- HDU 4777 Rabbit Kingdom
- hdu 4777 Rabbit Kingdom(离线+树状数组)
- hdu 4777 Rabbit Kingdom 离线树状数组
- hdu 4777 Rabbit Kingdom(树状数组)
- [HDU 4777 Rabbit Kingdom] 离线+树状数组
- HDU 4777 Rabbit Kingdom(树状数组)
- hdu 4777 Rabbit Kingdom(树状数组)
- hdu 4777 Rabbit Kingdom 离线+树状数组
- Hdu 4777 Rabbit Kingdom 树状数组
- hdu 4777 Rabbit Kingdom(树状数组)
- hdu 4777 Rabbit Kingdom 区间覆盖
- HDU 4777 Rabbit Kingdom [离线+树状数组]
- 火车进栈
- 第二届华东架构师大会成功召开
- Datatype length in mysql
- 程序员都该阅读的书
- 代码仔的实验室_微信公众平台开发框架 & Wechat Public Platform published on GitHub
- HDU 4777 Rabbit Kingdom 解题报告
- Windows-----Python的安装
- printf()函数输出格式
- dwr框架使用解析
- end_request: I/O error, dev mtdblock2, sector 0 Buffer I
- UVa 10285 / POJ 1088 Longest Run on a Snowboard (记忆化搜索)
- 我使用过的Linux命令之mv - 文件或目录改名、移动位置
- NKOJ1236 a^b
- C++特性笔记