CF 474/F, 线段树 + 一点数学
2016-07-15 10:51
288 查看
啊回家真是颓,一周了什么都没做
题目大意:给出一坨数,每次询问区间当中有多少个数能把其他区间内的所有数整除
解:由于我是知道这个是线段树专题,所以一开始就奔着gcd去了,想了一下还真是gcd,因为如果一个数a能整除另一个数b,那么gcd(a,b)一定为a,所以这说明可以做区间加法,直接上线段树就是,询问个数的时候还傻叉地想了一会,后面发现给每个线段记一下当前线段表示的gcd有几个就行,合并直接合并(可以证明现在这个线段的gcd一定是作为最优的取值,因为没有数等于这个gcd说明没有数能整除当前区间,那么合并上去也不会导致少解)
CF474F
题目大意:给出一坨数,每次询问区间当中有多少个数能把其他区间内的所有数整除
解:由于我是知道这个是线段树专题,所以一开始就奔着gcd去了,想了一下还真是gcd,因为如果一个数a能整除另一个数b,那么gcd(a,b)一定为a,所以这说明可以做区间加法,直接上线段树就是,询问个数的时候还傻叉地想了一会,后面发现给每个线段记一下当前线段表示的gcd有几个就行,合并直接合并(可以证明现在这个线段的gcd一定是作为最优的取值,因为没有数等于这个gcd说明没有数能整除当前区间,那么合并上去也不会导致少解)
#include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <complex> #include <set> #include <vector> #include <map> #include <queue> #include <deque> #include <ctime> using namespace std; const double EPS = 1e-8; #define ABS(x) ((x)<0?(-(x)):(x)) #define SQR(x) ((x)*(x)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define LSON(x) ((x)<<1) #define RSON(x) (((x)<<1)+1) #define LOWBIT(x) ((x)&(-(x))) #define MAXS 1111 #define MAXN 222222 #define VOIDPOINT 0 #define LL long long #define OO 214748364 struct segTree{ int gcd[MAXN*4], num[MAXN*4], l[MAXN*4], r[MAXN*4], mid[MAXN*4]; int gx, gy, gz; inline void updata(const int &kok) { gcd[kok] = __gcd(gcd[LSON(kok)], gcd[RSON(kok)]); num[kok] = (gcd[kok] == gcd[LSON(kok)] ? num[LSON(kok)] : 0) + (gcd[kok] == gcd[RSON(kok)] ? num[RSON(kok)] : 0); } void build(int kok, int ll, int rr, int *a) { l[kok] = ll; r[kok] = rr; if (ll == rr) { gcd[kok] = a[ll]; num[kok] = 1; return ; } int m = mid[kok] = (ll + rr) >> 1; build(LSON(kok), ll, m, a); build(RSON(kok), m+1, rr, a); updata(kok); } int getGCD(int kok) { if (gx <= l[kok] && r[kok] <= gy) { return gcd[kok]; } if (gy <= mid[kok]) return getGCD(LSON(kok)); else if (gx > mid[kok]) return getGCD(RSON(kok)); else return __gcd(getGCD(LSON(kok)), getGCD(RSON(kok))); } int query(int kok) const { if (gx <= l[kok] && r[kok] <= gy) { return gz == gcd[kok] ? num[kok] : 0; } if (gy <= mid[kok]) return query(LSON(kok)); else if (gx > mid[kok]) return query(RSON(kok)); else return (query(LSON(kok)) + query(RSON(kok))); } void set(int a = 0, int b = 0, int c = 0) { gx = a; gy = b; gz = c; } } Tree; int n, a[MAXN]; int main() { // freopen("test.txt", "r", stdin); scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d", a+i+1); } Tree.build(1, 1, n, a); int m, l, r, t; scanf("%d", &m); while (m--) { scanf("%d%d", &l, &r); Tree.set(l, r); t = Tree.getGCD(1); Tree.set(l, r, t); printf("%d\n", r - l - Tree.query(1) + 1); } return 0; }
CF474F
相关文章推荐
- 算法题(3)
- Android中visibility属性VISIBLE、INVISIBLE、GONE的区别
- Android检测View的可见性
- HDU 4811 Ball(超直白解释)
- jQuery效果(四)——动画
- Maven deploy时报Fatal error compiling: tools.jar not found错误的问题处理
- CentOS6.7搭建蜜罐dionaea
- android手机短信获取
- java ArrayList 源码浅析
- RequireJS基础(二)
- 利用jquery写无缝循环滑动的轮播图
- Html.ActionLink无法跳转
- 计算机专业工程硕士开题答辩
- java异常机制
- 线性筛求莫比乌斯反演函数+分块+前缀和
- JavaScript踩坑小计——变量的作用域和类型声明
- Django中实现文件下载功能
- [心得感想]16.7.14-21 DIARY
- Spring中的Aware
- nginx作反向代理,实现负载均衡