hdu 4630 No Pain No Game(树状数组离线操作)
来源:互联网 发布:国外网络流行模式 编辑:程序博客网 时间:2024/05/29 14:29
题目大意:
给你n个数分别为a1,a2,a3,a4,a5,a6,a7.......an。
询问 l.r 问区间[l.r]内的任意两个数的最大公约数是多少?
解决方法:
首先对查询区间按照左端点从大到小的顺序排序。
建立一个pre[i]数组记录,约数i上一次出现的位置,pre[i]初始值为-1。
建立一个树状数组,树状数组维护的是区间最大值。
然后依此对an,a(n-1),....a2,a1,进行处理,对于每个数求出其所有的约数,并且针对每个约数i,对树状数组进行修改,修改与区间和修改类似,但是将求和改为tree[i]=max(tree[i],v);
查询:当处理到第j个是时就要将左区间为j的所有查询都处理完毕,如果其右区间为r,结果就是树状数组前r项的最大值,用树状数组很容易就可以求出来。
我的代码:
#include <cstdio>#include <algorithm>#include <iostream>#include <cstring>#include <cmath>#define maxn 50010using namespace std;struct Point { int x,y,id,ans;}po[maxn];int pre[maxn];int tree[maxn];int num[maxn];int n,m;bool cmp(Point x, Point y){ return x.x<y.x;}bool cmp1(Point x,Point y){ return x.id<y.id;}int add(int x,int v){ //cout<<v<<endl; for (int i=x;i<=n;i+=i&(-i)) tree[i]=max(tree[i],v); return 0;}int maxx(int x){ int _max=-1; for (int i=x;i>0;i-=i&(-i)) _max=max(_max,tree[i]); return _max;}int change(int n){ int k=(int)sqrt(num[n]); //cout<<"num "<<num[n]<<endl; //cout<<"k "<<k<<endl; for (int i=1;i<=k;i++){ if (num[n]%i==0){ //cout<<" i "<<i<<endl; //cout<<" i "<<num[n]/i<<endl; if (i==k){ if (k*k==num[n]){ //cout<<"III"<<endl; if (pre[i]){ add(pre[i],i); pre[i]=n; } else pre[i]=n; } else { if (pre[i]){ add(pre[i],i); pre[i]=n; } else pre[i]=n; if (pre[num[n]/i]){ add(pre[num[n]/i],num[n]/i); pre[num[n]/i]=n; } else pre[num[n]/i]=n; } } else { if (pre[i]){ add(pre[i],i); pre[i]=n; } else pre[i]=n; if (pre[num[n]/i]){ add(pre[num[n]/i],num[n]/i); pre[num[n]/i]=n; } else pre[num[n]/i]=n; } } } return 0;}int main (){ //freopen("test.in","r",stdin); int T;scanf("%d",&T); while (T--){ memset(tree,0,sizeof(tree)); memset(pre,0,sizeof(pre)); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&num[i]); scanf("%d",&m); for (int i=1;i<=m;i++) scanf("%d%d",&po[i].x,&po[i].y),po[i].id=i; sort(po+1,po+m+1,cmp); int pos=n; for (int i=m;i>=1;i--){ while (po[i].x<=pos){ change(pos--); } if (po[i].x==po[i].y) po[i].ans=0; else po[i].ans=maxx(po[i].y); } sort(po+1,po+m+1,cmp1); for (int i=1;i<=m;i++) printf("%d\n",po[i].ans); } return 0;}
0 0
- HDU 4630 No Pain No Game 树状数组+离线操作
- HDU 4630 No Pain No Game(离线 + 树状数组)
- hdu 4630 No Pain No Game(树状数组离线操作)
- hdu 4630 no pain no game 树状数组+离线查询
- hdu-4630-No Pain No Game-(树状数组,离线处理)
- hdu 4630 No Pain No Game(线段树+离线操作)
- hdu 4630 No Pain No Game【线段树 离线操作】
- hdu 4630 No Pain No Game 线段树 树状数组
- HDU 4630 No Pain No Game 树状数组
- hdu 4630 No Pain No Game 树状数组
- No Pain No Game(树状数组)
- hdu 4630 No Pain No Game (区间gcd相关x线段树or树状数组)
- 树状数组no pain no game(hdu 2013多校contest3)
- HDU 4630 No Pain No Game 离线+线段树
- HDU 4630 No Pain No Game (线段树离线查询)
- HDU - 4630 No Pain No Game (线段树 + 离线处理)
- No Pain No Game(数状数组离线查询)
- HDU 4630 No Pain No Game(线段树离线处理)
- ios防止按钮多次点击
- openstack scheduler 配置参数说明
- java内部类总结
- Quality Settings说明
- HDU 4958 DP
- hdu 4630 No Pain No Game(树状数组离线操作)
- linux的w命令
- db2数据类型详解
- Java面向对象——封装
- 求一个数列的逆序数
- jquery阻止冒泡事件:$('span').bind("click",function(event){event.stopPropagation();})(有用源)
- WPF应用Binding之Path
- storm用于提高处理速度的并行度设计的感想2
- Spring quartz(定时器任务)