标签:style http color os io for 代码 ar
题意:给定一个序列,3种操作,单点添加值,查询区间和,把区间和变成最接近的婓波那契数
思路:线段树,就是第三个操作麻烦,就在结点添加一个值,标记它区间是不是都是婓波那契数了,然后修改区间的时候,如果区间是了就不用修改,如果不是就继续往后一层推即可
代码:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define lson(x) ((x<<1) + 1)
#define rson(x) ((x<<1) + 2)
typedef __int64 ll;
const ll INF = 2000000000000000LL;
const int N = 100005;
int n, m, fn;
ll Fib[100];
struct Node {
int l, r;
ll sum;
bool isFib;
} node[4 * N];
void pushup(int x) {
int l = lson(x);
int r = rson(x);
node[x].l = node[l].l; node[x].r = node[r].r;
node[x].isFib = (node[l].isFib && node[r].isFib);
node[x].sum = node[l].sum + node[r].sum;
}
void build(int l, int r, int x) {
if (l == r) {
node[x].l = l;
node[x].r = r;
node[x].sum = 0;
node[x].isFib = false;
return;
}
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
pushup(x);
}
ll abss(ll x) {
if (x < 0) return -x;
return x;
}
ll find(ll x) {
int l = 0, r = fn;
while (l < r) {
int mid = (l + r) / 2;
if (Fib[mid] < x) l = mid + 1;
else r = mid;
}
if (l == 0) return Fib[0];
ll ll = Fib[l - 1], rr = Fib[l];
if (abss(x - ll) <= abss(x - rr))
return ll;
else return rr;
}
void add(int k, ll v, int x) {
if (node[x].l == k && node[x].r == k) {
node[x].sum += v;;
node[x].isFib = (find(node[x].sum) == node[x].sum);
return;
}
int mid = (node[x].l + node[x].r) / 2;
if (k <= mid) add(k, v, lson(x));
if (k > mid) add(k, v, rson(x));
pushup(x);
}
void insert(int l, int r, int x) {
if (node[x].isFib) return;
if (node[x].l == node[x].r) {
node[x].sum = find(node[x].sum);
node[x].isFib = true;
return;
}
int mid = (node[x].l + node[x].r) / 2;
if (l <= mid) insert(l, r, lson(x));
if (r > mid) insert(l, r, rson(x));
pushup(x);
}
ll query(int l, int r, int x) {
if (node[x].l >= l && node[x].r <= r)
return node[x].sum;
int mid = (node[x].l + node[x].r) / 2;
ll ans = 0;
if (l <= mid) ans += query(l, r, lson(x));
if (r > mid) ans += query(l, r, rson(x));
return ans;
}
int main() {
Fib[0] = Fib[1] = 1;
for (fn = 2; ; fn++) {
Fib[fn] = Fib[fn - 2] + Fib[fn - 1];
if (Fib[fn] > INF) break;
}
while (~scanf("%d%d", &n, &m)) {
build(1, n, 0);
int Q, a, b;
ll v;
while (m--) {
scanf("%d", &Q);
if (Q == 1) {
scanf("%d%I64d", &a, &v);
add(a, v, 0);
}
else if (Q == 2) {
scanf("%d%d", &a, &b);
printf("%I64d\n", query(a, b, 0));
}
else {
scanf("%d%d", &a, &b);
insert(a, b, 0);
}
}
}
return 0;
}HDU Wow! 4893 Such Sequence!(线段树),布布扣,bubuko.com
HDU Wow! 4893 Such Sequence!(线段树)
标签:style http color os io for 代码 ar
原文地址:http://blog.csdn.net/accelerator_/article/details/38276679