[区间GCD预处理 树状数组 离线] HDU 5869 Different GCD Subarray Query
来源:互联网 发布:js数组删除元素splice 编辑:程序博客网 时间:2024/05/21 05:39
首先确定一个右端点 向左做后缀gcd的值是不超过log的 因为gcd必然递减 每次至少除以2
那么可以对每个右端点预处理出来
然后要求区间不同的gcd个数 这里要用到1878: [SDOI2009]HH的项链的技巧
用树状数组离线处理
按右端点的顺序处理询问
令pos[x]等于x这个值出现的最靠右的位置 显然这里是对计算贡献最有利的 然后用树状数组维护下 对于某个位置 有多少个pos的取值是在这里的
#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define cl(x) memset(x,0,sizeof(x))using namespace std;typedef long long ll;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++;}inline int read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; else if (c==EOF) return 0; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; return 1;}const int N=100005;int n,m,a[N];struct abcd{ int l,r,d; abcd(int l=0,int r=0,int d=0):l(l),r(r),d(d) {}}G[N][35];int cnt[N];inline void Init(){ for (int i=1;i<=n;i++){ for (int j=1;j<=cnt[i-1];j++) G[i][j]=G[i-1][j],G[i][j].d=__gcd(G[i][j].d,a[i]); cnt[i]=cnt[i-1]+1; G[i][cnt[i]]=abcd(i,i,a[i]); int pnt=0; for (int j=1;j<=cnt[i];j++){ if (G[i][j].d!=G[i][pnt].d) G[i][++pnt]=G[i][j]; else G[i][pnt].r=G[i][j].r; } cnt[i]=pnt; }}namespace BIT{ int maxn; ll c[N]; inline void init(int n){ maxn=n; for (int i=1;i<=n;i++) c[i]=0; } inline void add(int x,int r){ for (int i=x;i<=maxn;i+=i&-i) c[i]+=r; } inline ll sum(int x) { int ret=0; for (int i=x;i;i-=i&-i) ret+=c[i]; return ret; } inline ll sum(int l,int r) { return sum(r)-sum(l-1); }}struct event{ int l,r,idx; bool operator < (const event &B) const{ return r<B.r; }}eve[N];int tot;ll ans[N];int pos[1000005];int main(){ int T,l,r,Case=0; freopen("t.in","r",stdin); freopen("t.out","w",stdout); while (read(n)){ read(tot); for (int i=1;i<=n;i++) read(a[i]); Init(); BIT::init(n); for (int i=1;i<=tot;i++) read(eve[i].l),read(eve[i].r),eve[i].idx=i; sort(eve+1,eve+tot+1); int pnt=1; for (int i=1;i<=n;i++){ for (int j=1;j<=cnt[i];j++){ int d=G[i][j].d,r=G[i][j].r; if (pos[d]) BIT::add(pos[d],-1); pos[d]=max(r,pos[d]); BIT::add(pos[d],1); } while (pnt<=tot && eve[pnt].r==i) ans[eve[pnt].idx]=BIT::sum(eve[pnt].l,eve[pnt].r),pnt++; } for (int i=1;i<=tot;i++) printf("%I64d\n",ans[i]); cl(pos); } return 0;}
0 0
- [区间GCD预处理 树状数组 离线] HDU 5869 Different GCD Subarray Query
- hdu-5869 Different GCD Subarray Query gcd预处理 + 树状数组 + 离线
- HDU 5869 Different GCD Subarray Query 离线 树状数组
- hdu 5869 Different GCD Subarray Query 离线+树状数组
- HDU 5869 Different GCD Subarray Query(离线处理+树状数组)
- HDU 5869 Different GCD Subarray Query (离线处理 树状数组)
- HDU 5869 Different GCD Subarray Query [区间gcd预处理+离线]【数据结构】
- hdu 5869 Different GCD Subarray Query(gcd+树状数组)
- HDU 5869 Different GCD Subarray Query (数学gcd+树状数组离线查询)
- hdu 5869 Different GCD Subarray Query 预处理 + 离线
- HDU 5869 Different GCD Subarray Query 树状数组
- hdu5869 Different GCD Subarray Query(预处理+树状数组)
- HDU5869 Different GCD Subarray Query (离线+树状数组)
- [离线+树状数组] HDU5869 Different GCD Subarray Query
- HDU 5869 Different GCD Subarray Query(离线+gcd)
- HDU 5869 Different GCD Subarray Query(计数区间不同GCD)
- 2016 大连网络赛 hdu 5869 Different GCD Subarray Query(gcd+树状数组)★ ★
- Hdu-5869 Different GCD Subarray Query(区间不同值离线算法)
- web.xml 配置介绍
- 移动开发人机交互
- 1039. Course List for Student (25)PAT甲级
- Ability To Convert
- Wifi模块——ESP8266(三)
- [区间GCD预处理 树状数组 离线] HDU 5869 Different GCD Subarray Query
- BZOJ3164: [Heoi2013]Eden的博弈问题
- Add Two Numbers
- File类
- 关于Linux xfs文件系统修复的文章
- Android开机自启动应用通过广播
- redis INFO命令详解
- (六)选项卡的设置
- java的String类和StringBuffer的应用 冒泡排序 选择元素 二分查找