模板:区间GCD
2018-02-09 16:21
351 查看
一、RMQ实现
RMQ不能实现更新。#include <iostream>#include <sstream>
#include <iomanip>
#include <string>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <utility>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN = 100100;
const int MOD7 = 1e9 + 7;
const int MOD9 = 1e9 + 9;
const int INF = 2e9;
const double EPS = 1e-6;
const double PI = 3.14159265358979;
const int dir_4r[] = { -1, 1, 0, 0 };
const int dir_4c[] = { 0, 0, -1, 1 };
const int dir_8r[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dir_8c[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
int input[MAXN];
int dp[MAXN][20];
int GCD(int a, int b) {
int r;
while (b) {
r = a % b;
a = b;
b = r;
}
return a;
}
//RMQ初始化
void init(int n) {
for (int i = 0; i < n; ++i)
dp[i][0] = input[i];
for (int j = 1; (1 << j) <= n; ++j)
for (int i = 0; i + (1 << j) - 1 < n; ++i)
dp[i][j] = GCD(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
int getGcd(int l, int r) {
int k = 0;
while ((1 << (k + 1)) <= r - l + 1)
k++;
return GCD(dp[l][k], dp[r - (1 << k) + 1][k]);
}
int main() {
//system("pause");
return 0;
}
二、线段树实现
线段树能够实现更新#include <iostream>#include <sstream>
#include <iomanip>
#include <string>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <utility>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN = 500500;
const int MOD7 = 1e9 + 7;
const int MOD9 = 1e9 + 9;
const int INF = 2e9;
const double EPS = 1e-6;
const double PI = 3.14159265358979;
const int dir_4r[] = { -1, 1, 0, 0 };
const int dir_4c[] = { 0, 0, -1, 1 };
const int dir_8r[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dir_8c[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
#define lson (rt*2+1)
#define rson (rt*2+2)
struct Node {
int l, r;
int val;
int mid() { return (l + r) >> 1; }
};
Node tree[MAXN << 2];
int input[MAXN];
int GCD(int a, int b) {
int r;
while (b) {
r = a%b;
a = b;
b = r;
}
return a;
}
void buildTree(int rt, int l, int r) {
tree[rt].l = l;
tree[rt].r = r;
if (l == r)
tree[rt].val = input[l];
else {
int mid = tree[rt].mid();
buildTree(lson, l, mid);
buildTree(rson, mid + 1, r);
tree[rt].val = GCD(tree[lson].val, tree[rson].val);
}
}
//单点更新
void update(int rt, int pos, int val) {
if (tree[rt].l == tree[rt].r) {
tree[rt].val = val;
return;
}
int mid = tree[rt].mid();
if (pos <= mid)
update(lson, pos, val);
else
update(rson, pos, val);
tree[rt].val = GCD(tree[lson].val, tree[rson].val);
}
int query(int rt, int l, int r) {
if (tree[rt].l == l && tree[rt].r == r)
return tree[rt].val;
int mid = tree[rt].mid();
if (mid >= r)
return query(lson, l, r);
else if (mid < l)
return query(rson, l, r);
else {
int q1 = query(lson, l, mid);
int q2 = query(rson, mid + 1, r);
return GCD(q1, q2);
}
}
int main() {
//system("pause");
return 0;
}
相关文章推荐
- HDU 5869 求区间中不同连续序列的gcd的个数(树状数组)
- 【C++】C++11特性:模板推导和循环区间
- 【模板】快速区间素数计数
- RMQ模板 求区间最大、最小值。 (前提是数组一旦确定便不再频繁更改)
- 扩展gcd模板,a^x=b。
- ACM Sparse Table(模板+区间相关)
- POJ - 3468线段树--区间求和模板
- 【模板】树状数组 区间修改,区间求和 (模板题:洛谷P3368树状数组2)
- HDU 5381 The sum of gcd (莫队 + 二分 + 区间GCD特性)
- luogu1890 gcd区间(线段树/预处理)
- POJ 3468 A Simple Problem with Integers (线段树区间更新模板)
- 区间重叠的合并模板
- XXFSDDX HDU6119 区间合并模板(交叉区间去重)
- hdu_5726_GCD(线段树维护区间+预处理)
- AC的故事大结局悲剧版(下) 主席树模板,区间修改
- poj3468 A Simple Problem with Integers(线段树+区间更新+非完全替换)模板
- hihocoder 1078 线段树的区间修改 (线段树 区间更新 模板)
- HDU 5726 区间GCD=k的个数
- 线段树模板(区间和最大值最下值)
- HDU 1698 线段树区间更新模板