FZU2224 An exciting GCD problem 区间gcd预处理+树状数组
分析:(别人写的)
对于所有(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预处理+树状数组的更多相关文章
- 区间gcd问题 HDU 5869 离线+树状数组
题目大意:长度n的序列, m个询问区间[L, R], 问区间内的所有子段的不同GCD值有多少种. 子段就是表示是要连续的a[] 思路:固定右端点,预处理出所有的gcd,每次都和i-1的gcd比较,然后 ...
- ACM学习历程—51NOD 1685 第K大区间2(二分 && 树状数组 && 中位数)
http://www.51nod.com/contest/problem.html#!problemId=1685 这是这次BSG白山极客挑战赛的E题. 这题可以二分答案t. 关键在于,对于一个t,如 ...
- [BZOJ2225][SPOJ2371]LIS2 - Another Longest Increasing Subsequence Problem:CDQ分治+树状数组+DP
分析 这回试了一下三级标题,不知道效果怎么样? 回到正题,二维最长上升子序列......嗯,我会树套树. 考虑\(CDQ\)分治,算法流程: 先递归进入左子区间. 将左,右子区间按\(x\)排序. 归 ...
- HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...
- 【HDU4947】GCD Array(莫比乌斯反演+树状数组)
点此看题面 大致题意: 一个长度为\(n\)的数组,实现两种操作:将满足\(gcd(i,k)=d\)的\(a_i\)加上\(v\),询问\(\sum_{i=1}^xa_i\). 对于修改操作的推式子 ...
- A Simple Problem with Integers 多树状数组分割,区间修改,单点求职。 hdu 4267
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- poj_3468: A Simple Problem with Integers (树状数组区间更新)
题目是对一个数组,支持两种操作 操作C:对下标从a到b的每个元素,值增加c: 操作Q:对求下标从a到b的元素值之和. 这道题也可以用线段树解,本文不做描述,下面分析如何用树状数组来解决这道题. 先把问 ...
- POJ 3468 A Simple Problem with Integers(树状数组区间更新)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 97217 ...
- poj 3468: A Simple Problem with Integers (树状数组区间更新)
题目链接: http://poj.org/problem?id=3468 题目是对一个数组,支持两种操作 操作C:对下标从a到b的每个元素,值增加c: 操作Q:对求下标从a到b的元素值之和. 这道题也 ...
随机推荐
- hdu 4850 Wow! Such String! 欧拉回路
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4080264.html 题目链接:hdu 4850 Wow! Such String! 欧拉回 ...
- 用C#开发一个WinForm版的批量图片压缩工具
我们在实际项目开发过程中,曾经遇到过一个需求,就是要开发一个对大量图片进行整理(删除掉一些不符合要求的图片).归类(根据格式进行分类,比如jpg格式.bmp格式等).压缩(因为有的图片很大很占空间,看 ...
- shopnc 商城源码阅读笔记-缓存技术
缓存方式 : 从 shopnc 的缓存驱动目录 /framework/cache里已有的实现类来看,shopnc支持以下5种缓存方式 apc Eaccelerator file memcache xc ...
- jquery验证手机号码、邮箱格式是否正确示例代码
本文为大家介绍下使用jquery验证邮箱.验证手机号码,具体实现思路及代码如下,感兴趣的朋友可以学习下 复制代码代码如下: //jquery验证邮箱 function checkSubmitEmai ...
- js:合同-已知起始日期、年限,自动计算截止日期
dateAddYear('2016-01-01', '3') ;//返回:2018-12-31 浏览器:ie11,ff 46.0.1(成功)360v8.1(急速模式,成功) 浏览器:360v8.1(兼 ...
- python学习_应用pickle模块封装和拆封数据对象
学习文件数据处理的时候了解到有pickle模块,查找官方文档学习了一些需要用到的pickle内容. 封装是一个将Python数据对象转化为字节流的过程,拆封是封装的逆操作,将字节文件或字节对象中的字节 ...
- 【jsp+jpa】Check your ViewResolver setup!
困扰了好几天的坑 javax.servlet.ServletException: Circular view path [fileupload]: would dispatch back to the ...
- 关于oi
2015-12-26 今天在机房,楼上的孩子发下来一个exe,善良无知的我打开了那个exe,然后电脑就关机了.萌萌的辅导老师看到之后就不再萌萌哒,他跑到五楼训斥了那群孩子们一顿(自行脑补).出于报复, ...
- Grails的redirect无法跳转时的一个可能原因
由于controller的命名一般首字母大写,如Login 此时如 class LoginController { def index = { redirect(action:Login, param ...
- 1007: [HNOI2008]水平可见直线
先对a排序,a相等的话就对b排序: 维护一个栈,每次取栈的头两个,和当前的直线相比较: 如果当前的直线把头第一个屏蔽,就将他出栈,一直到不能屏蔽为止: 代码: #include<cstdio&g ...