HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869
问你l~r之间的连续序列的gcd种类。
首先固定右端点,预处理gcd不同尽量靠右的位置(此时gcd种类不超过loga[i]种)。
预处理gcd如下代码,感觉真的有点巧妙...
for(int i = ; i <= n; ++i) {
int x = a[i], y = i;
for(int j = ; j < ans[i - ].size(); ++j) {
int gcd = GCD(x, ans[i - ][j].first);
if(gcd != x) {
ans[i].push_back(make_pair(x, y));
x = gcd, y = ans[i - ][j].second;
}
}
ans[i].push_back(make_pair(x, y));
}
然后用树状数组维护右端点固定的gcd位置。
//#pragma comment(linker, "/STACK:102400000, 102400000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
typedef pair <int, int> P;
const int N = 1e6 + ;
int a[N/ + ], bit[N], _pos[N]; //_pos存的是gcd上一次出现的位置
vector <P> ans[N/ + ]; //存的是以i为右端点的gcd
struct query {
int l, r, pos;
bool operator <(const query& cmp) const {
return r < cmp.r;
}
}q[N/ + ];
int res[N/ + ]; //答案 void init(int n) {
memset(_pos, , sizeof(_pos));
memset(bit, , sizeof(bit));
for(int i = ; i <= n; ++i) {
ans[i].clear();
}
} int GCD(int a, int b) {
return b ? GCD(b, a % b): a;
} void add(int i, int x) {
for( ; i <= N; i += (i&-i))
bit[i] += x;
} int sum(int i) {
int s = ;
for( ; i >= ; i -= (i&-i))
s += bit[i];
return s;
} int main()
{
int n, m;
while(scanf("%d %d", &n, &m) != EOF) {
init(n);
for(int i = ; i <= n; ++i) {
scanf("%d", a + i);
}
for(int i = ; i <= m; ++i) {
scanf("%d %d", &q[i].l, &q[i].r);
q[i].pos = i;
}
for(int i = ; i <= n; ++i) {
int x = a[i], y = i;
for(int j = ; j < ans[i - ].size(); ++j) {
int gcd = GCD(x, ans[i - ][j].first);
if(gcd != x) {
ans[i].push_back(make_pair(x, y));
x = gcd, y = ans[i - ][j].second;
}
}
ans[i].push_back(make_pair(x, y));
}
sort(q + , q + m + );
int p = ;
for(int i = ; i <= n; ++i) {
for(int j = ; j < ans[i].size(); ++j) {
if(!_pos[ans[i][j].first]) {
add(ans[i][j].second, );
_pos[ans[i][j].first] = ans[i][j].second;
} else {
add(_pos[ans[i][j].first], -);
_pos[ans[i][j].first] = ans[i][j].second;
add(ans[i][j].second, );
}
}
while(i == q[p].r && p <= m) {
res[q[p].pos] = sum(q[p].r) - sum(q[p].l - );
++p;
}
}
for(int i = ; i <= m; ++i) {
printf("%d\n", res[i]);
}
}
return ;
}
HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)的更多相关文章
- FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2224 同hdu5869 //#pragma comment(linker, "/STACK:1024 ...
- 2016 大连网赛---Different GCD Subarray Query(GCD离散+树状数组)
题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5869 Problem Description This is a simple probl ...
- FZU2224 An exciting GCD problem 区间gcd预处理+树状数组
分析:(别人写的) 对于所有(l, r)区间,固定右区间,所有(li, r)一共最多只会有log个不同的gcd值, 可以nlogn预处理出所有不同的gcd区间,这样区间是nlogn个,然后对于询问离线 ...
- HDU 6203 ping ping ping(dfs序+LCA+树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意: n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V 无法连 ...
- HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...
- HDU 5465 Clarke and puzzle Nim游戏+二维树状数组
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle Accepts: 42 Submissions: 26 ...
- hdu 1166 敌兵布阵——(区间和)树状数组/线段树
pid=1166">here:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Input 第一行一个整数T.表示有T组数据. 每组数据第一 ...
- HDU 2838 (DP+树状数组维护带权排序)
Reference: http://blog.csdn.net/me4546/article/details/6333225 题目链接: http://acm.hdu.edu.cn/showprobl ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
随机推荐
- (转)iOS动画Core Animation
文章转载:http://blog.sina.com.cn/s/blog_7b9d64af0101b8nh.html 在iOS中动画实现技术主要是:Core Animation. Core Animat ...
- POJ 3308 Paratroopers (对数转换+最小点权覆盖)
题意 敌人侵略r*c的地图.为了消灭敌人,可以在某一行或者某一列安置超级大炮.每一个大炮可以瞬间消灭这一行(或者列)的敌人.安装消灭第i行的大炮消费是ri.安装消灭第j行的大炮消费是ci现在有n个敌人 ...
- Linux kernel scriptes bin2c "\x"
/**************************************************************************** * Linux kernel scripte ...
- AIX 第4章 指令记录
root@db:/#lsdev -Cc disk --查看磁盘设备信息 -C customized -c class hdisk0 Available 00-08-00 SAS Dis ...
- ORA-10456:cannot open standby database;media recovery session may be in process
http://neeraj-dba.blogspot.com/2011/10/ora-10456-cannot-open-standby-database.html Once while star ...
- cocos2dc-x解决中文乱码
中文乱码: 方法一: 选中有中文的那个cpp,点文件另存为,在保存这里竟然有个小箭头 点之,再点编码保存 再选这个编码 这个cpp就UTF-8化了,然后中文就正常了. 但是发现:但字符串字符数为奇数时 ...
- Android按键事件传递流程(二)
5 应用层如何从Framework层接收按键事件 由3.2和4.5.4节可知,当InputDispatcher通过服务端管道向socket文件描述符发送消息后,epoll机制监听到了I/O事件, ...
- Android源码分析--CircleImageView 源码详解
源码地址为 https://github.com/hdodenhof/CircleImageView 实际上就是一个圆形的imageview 的自定义控件.代码写的很优雅,实现效果也很好, 特此分析. ...
- Linux makefile教程之书写命令四[转]
书写命令———— 每 条规则中的命令和操作系统Shell的命令行是一致的.make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非,命令是紧跟 在依赖规则后面的分号后的.在命令 ...
- WCF服务通过防火墙怎么设置
设置防火墙 1.首先点击控制面板->系统与安全->Window防火墙->点击允许程序通过Windows防火墙 2.查找Windows Communication Foundation ...