分析:(别人写的)

对于所有(l, r)区间,固定右区间,所有(li, r)一共最多只会有log个不同的gcd值,

可以nlogn预处理出所有不同的gcd区间,这样区间是nlogn个,然后对于询问离线处理,

用类似询问区间不同数字的方法,记录每个不同gcd最后出现的位置,然后用树状数组进行维护

注:我是看了这段文字会的,但是他的nlogn预处理我不会,我会nlog^2n的

dp[i][j]代表以i为右端点,向左延伸2^j个点(包括i)的gcd,然后因为这样的gcd满足递减,所以可以二分找区间

代码:

/*RunID: 678021
UserID: 96655
Submit time: 2016-04-19 23:44:20
Language: C++
Length: 2378 Bytes.
Result: Accepted
*/ #include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int N=1e4+;
int T,n,m,dp[N][];
struct ask{
int l,r,id;
bool operator<(const ask &rhs)const{
return r<rhs.r;
}
}p[N*];
struct Seg{
int l,r,v;
bool operator<(const Seg &rhs)const{
return r<rhs.r;
}
}seg[*N];
int erfen(int pos,int v){
int l=,r=pos;
while(l<r){
int mid=(l+r)>>;
int len=pos-mid+;
int now=pos,cur=-;
for(int i=;i>=;--i){
if(len&(<<i)){
if(cur==-)cur=dp[now][i];
else cur=__gcd(cur,dp[now][i]);
now-=(<<i);
}
}
if(cur<v)l=mid+;
else r=mid;
}
return (l+r)>>;
}
int hash[*N],tot,mat[*N];
int res[N*];
int c[N];
void add(int x,int t){
for(int i=x;i<=n;i+=i&(-i))
c[i]+=t;
}
int get(int x){
int ans=;
if(x==)return ;
for(int i=x;i>;i-=i&(-i))
ans+=c[i];
return ans;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
scanf("%d",&dp[i][]);
for(int i=;i<=m;++i)
scanf("%d%d",&p[i].l,&p[i].r),p[i].id=i;
for(int k=;(<<k)<=n;++k)
for(int i=n;i>;--i){
int j=i-(<<k)+;
if(j<)break;
j=i-(<<(k-));
dp[i][k]=__gcd(dp[i][k-],dp[j][k-]);
}
int cnt=;tot=;
for(int i=;i<=n;++i){
int last=-;
for(int j=i;j>;--j){
int tmp=dp[j][];
if(last!=-)tmp=__gcd(tmp,last);
last=tmp;
++cnt;
seg[cnt].l=j,seg[cnt].r=i,seg[cnt].v=last;
hash[++tot]=last;
j=erfen(i,last);
}
}
sort(hash+,hash++tot);
tot=unique(hash+,hash++tot)-hash-;
sort(p+,p++m);
sort(seg+,seg++cnt);
memset(mat,,sizeof(mat));
memset(c,,sizeof(c));
int now=;
for(int i=;i<=m;++i){
for(;now<=cnt&&seg[now].r<=p[i].r;++now){
int pos=lower_bound(hash+,hash++tot,seg[now].v)-hash;
if(seg[now].l>mat[pos]){
if(mat[pos])add(mat[pos],-);
add(seg[now].l,);
mat[pos]=seg[now].l;
}
}
res[p[i].id]=get(p[i].r)-get(p[i].l-);
}
for(int i=;i<=m;++i)
printf("%d\n",res[i]);
}
return ;
}

FZU2224 An exciting GCD problem 区间gcd预处理+树状数组的更多相关文章

  1. 区间gcd问题 HDU 5869 离线+树状数组

    题目大意:长度n的序列, m个询问区间[L, R], 问区间内的所有子段的不同GCD值有多少种. 子段就是表示是要连续的a[] 思路:固定右端点,预处理出所有的gcd,每次都和i-1的gcd比较,然后 ...

  2. ACM学习历程—51NOD 1685 第K大区间2(二分 && 树状数组 && 中位数)

    http://www.51nod.com/contest/problem.html#!problemId=1685 这是这次BSG白山极客挑战赛的E题. 这题可以二分答案t. 关键在于,对于一个t,如 ...

  3. [BZOJ2225][SPOJ2371]LIS2 - Another Longest Increasing Subsequence Problem:CDQ分治+树状数组+DP

    分析 这回试了一下三级标题,不知道效果怎么样? 回到正题,二维最长上升子序列......嗯,我会树套树. 考虑\(CDQ\)分治,算法流程: 先递归进入左子区间. 将左,右子区间按\(x\)排序. 归 ...

  4. HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...

  5. 【HDU4947】GCD Array(莫比乌斯反演+树状数组)

    点此看题面 大致题意: 一个长度为\(n\)的数组,实现两种操作:将满足\(gcd(i,k)=d\)的\(a_i\)加上\(v\),询问\(\sum_{i=1}^xa_i\). 对于修改操作的推式子 ...

  6. A Simple Problem with Integers 多树状数组分割,区间修改,单点求职。 hdu 4267

    A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  7. poj_3468: A Simple Problem with Integers (树状数组区间更新)

    题目是对一个数组,支持两种操作 操作C:对下标从a到b的每个元素,值增加c: 操作Q:对求下标从a到b的元素值之和. 这道题也可以用线段树解,本文不做描述,下面分析如何用树状数组来解决这道题. 先把问 ...

  8. POJ 3468 A Simple Problem with Integers(树状数组区间更新)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 97217   ...

  9. poj 3468: A Simple Problem with Integers (树状数组区间更新)

    题目链接: http://poj.org/problem?id=3468 题目是对一个数组,支持两种操作 操作C:对下标从a到b的每个元素,值增加c: 操作Q:对求下标从a到b的元素值之和. 这道题也 ...

随机推荐

  1. php中的preg系列函数

    mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int ...

  2. 2011年-CUshell编程大赛

    今天群里有人在做练习时遇到一个问题,$0中的分隔符使用OFS没有成功作用,遂查到这个问题,留作备忘查看 http://bbs.chinaunix.net/thread-2319120-1-1.html

  3. JAVA技术体系发展路线

    JAVA技术体系 1.1 Java程序员 ·高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变参数.可变返回类型.增强循环.静态导入 ·核心编程 IO.多线程.实体类.集合类.正则表达式.XM ...

  4. 分享零基础学习Hadoop方法

    (我不是Hadoop专家,也只是一个初学者,这里我也只是就自己的学习体会,站在初学者的角度谈一下如何入门.) 首先我觉得应该思考这样一个问题:Hadoop对于我们来讲,是一种工具,那么Hadoop帮助 ...

  5. 一步步学习NHibernate(8)——HQL查询(2)

    请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,老魏带着大家学习了HQL语句,发现HQL语句还是非常不错的,尤其是在懒加载的时候,书写起来比较的舒服,但是这里老魏 ...

  6. The partner transaction manager has disabled its support for remote/network transactions.

    http://technet.microsoft.com/en-us/library/cc753510(WS.10).aspx

  7. 解决Deprecated: preg_replace(): The /e modifier is deprecated, use

    使用php5.5运行ecshop的时候出现如下错误Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace ...

  8. easyui源码翻译1.32--ComboTree(树形下拉框)

    前言 扩展自$.fn.combo.defaults和$.fn.tree.defaults.使用$.fn.combotree.defaults重写默认值对象.下载该插件翻译源码 树形下拉框结合选择控件和 ...

  9. jacob访问ocx控件方法和遇到的问题

    最近在进行摄像机的二次开发,摄像机厂商提供了使用C++开发的ocx控件:所以尝试使用jacob来进行访问. 操作步骤如下: 1, 从官网(http://sourceforge.net/projects ...

  10. PieTTY

    PieTTY 用 pietty 連上主機時 鍵盤右方數字鍵 (keypad) 失效的問題 用 pietty 連上主機時 鍵盤右方數字鍵 (keypad) 失效的問題 應該滿多人用 pietty 連上程 ...