分析:(别人写的)

对于所有(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. SQL Server 2012 读写分离设置

    SQL Server 2012 读写分离设置 - AlsoIn 时间 2014-07-21 17:38:00  博客园-所有随笔区 原文  http://www.cnblogs.com/also/p/ ...

  2. GroupBox 重绘圆角边框和文字

    private void GroupBox_Paint(object sender, PaintEventArgs e) { if (sender != null && sender ...

  3. 前端资源多个产品整站一键打包&包版本管理(二)——如何在bower的配置文件加上注释

    问题: 当一个工程里面有好几个项目,每个项目引用同一个包,但是不同的名字,例如在bower中 fancybox 跟 jquery.fancybox 是一样的,我们只需要下载其中的一个版本,而打包工作不 ...

  4. IE 6/7下自赋值导致 overflow 溢出

    情景是要限制一个textarea的最大输入字数(100字,  这字数限制也太少了点吧,不大气) 由于限制输入后需要允许 回退,全选等功能键,故放弃keyup, keydown组合 选用property ...

  5. Oracle 事务相关的一些测试

    1.sqlplus 客户端正常退出 SQL> desc t; 名称 是否为空? 类型 ----------------------------------------- -------- --- ...

  6. 基于C#的SolidWorks插件开发(1)--SolidWorks API接口介绍

    这是两年前毕业时写的一篇关于SolidWorks插件开发与公司PDM集成的毕业设计,最近闲来无事拿出来整理一下,大神们可以略过. 1.1   SolidWorks API接口 正确调用SolidWor ...

  7. 一步步学习ASP.NET MVC3 (8)——EmptyResult,ContentResult,RedirectResult

    请注明转载地址:http://www.cnblogs.com/arhat 上一章,我们阐述了Controller,Action和ActionResult所代表的含义及使用,本章继续研究ActionRe ...

  8. MyEclipse启动和运行速度优化

    1:去除不需要加载的模块 Windows – Preferences - General - Startup and Shutdown,这个时候在右侧就显示出了Eclipse启动时加载的模块,可以根据 ...

  9. Android Learning:微信第三方登录

    这两天,解决了微信第三方授权登录的问题,作为一个新手,想想也是一把辛酸泪.我想着,就把我的遇到的坑给大家分享一下,避免新手遇到我这样的问题能够顺利避开. 步骤一 微信开发者平台 我开始的解决思路是,去 ...

  10. XSS高级实战教程

    1.[yueyan科普系列]XSS跨站脚本攻击--yueyan 2.存储型XSS的成因及挖掘方法--pkav 3.跨站脚本攻击实例解析--泉哥 4.XSS高级实战教程--心伤的瘦子 5.XSS利用与挖 ...