首页 > 代码库 > HDU 4893 Wow! Such Sequence! 水线段树

HDU 4893 Wow! Such Sequence! 水线段树

思路:

线段树走起。。

写完这题就退役T^T

单点更新的时候直接找到这个点的最近fib,然后维护当前和 和 fib的和


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define mod 1000000007
#define N 200000
#define ll long long
ll f[100];
inline ll Mid(ll x, ll y){return (x+y)>>1;}
ll find(ll x){
    ll id = lower_bound(f, f+90, x) - f;
    if(f[id] == x || id==0)return f[id];
    if(f[id] - x >= x - f[id-1])
        return f[id-1];
    else return f[id];
}
struct node{
    ll l, r;
    ll sum, bsum;
    ll lazy;
}tree[N<<2];
void push_down(ll id){
    if(tree[id].lazy == 0)return ;
    tree[id].lazy = 0;
    if(tree[id].l == tree[id].r)
        return ;

    tree[L(id)].sum = tree[L(id)].bsum;
    tree[R(id)].sum = tree[R(id)].bsum;
    tree[L(id)].lazy = tree[R(id)].lazy = 1;
}
void push_up(ll id){
    tree[id].sum  = tree[L(id)].sum + tree[R(id)].sum;
    tree[id].bsum  = tree[L(id)].bsum + tree[R(id)].bsum;
}
void build(ll l, ll r, ll id){
    tree[id].l = l; tree[id].r = r;
    tree[id].sum = 0; tree[id].bsum = 0;
    tree[id].lazy = 0;
    if(l == r)
    {
        tree[id].bsum = find(0);
        return ;
    }
    ll mid = Mid(l, r);
    build(l, mid, L(id));
    build(mid+1, r, R(id));
    push_up(id);
}
ll query(ll l, ll r, ll id){
    push_down(id);
    if(l == tree[id].l && tree[id].r == r)
        return tree[id].sum;
    ll mid = Mid(tree[id].l, tree[id].r), ans = 0;
    if(mid < l)
        ans = query(l, r, R(id));
    else if(r <= mid)
        ans = query(l, r, L(id));
    else ans = query(l, mid, L(id)) + query(mid+1, r, R(id));
    push_up(id);
    return ans;
}
void updata(ll pos, ll add, ll id){
    push_down(id);
    if(tree[id].l == tree[id].r)
    {
        tree[id].sum += add;
        tree[id].bsum = find(tree[id].sum);
        return ;
    }
    ll mid = Mid(tree[id].l, tree[id].r);
    if(mid < pos)
        updata(pos, add, R(id));
    else if(pos <= mid)
        updata(pos, add, L(id));
    push_up(id);
}
void updata2(ll l, ll r, ll id){
    push_down(id);
    if(l == tree[id].l && tree[id].r == r)
    {
        tree[id].lazy = 1;
        tree[id].sum = tree[id].bsum;
        return ;
    }
    ll mid = Mid(tree[id].l, tree[id].r);
    if(mid < l)
        updata2(l, r, R(id));
    else if(r <= mid)
        updata2(l, r, L(id));
    else {
        updata2(l, mid, L(id));
        updata2(mid+1, r, R(id));
    }
    push_up(id);
}
ll n, m;
int main(){
    ll u, v, i, j, op;
    f[0] = f[1] = 1;
    for(i = 2; i < 90; i++)f[i] = f[i-1] + f[i-2];
    while(cin>>n>>m){
        build(1, n, 1);
        while(m--)
        {
            scanf("%I64d %I64d %I64d",&op,&u,&v);
            if(op==1)
                updata(u, v, 1);
            else if(op==2)
                printf("%I64d\n", query(u, v, 1));
            else 
                updata2(u, v, 1);
            //    for(i = 1; i <= n; i++)                cout<<query(i, i, 1)<<" ";             puts("");
        }
    }
    return 0;
}
/*
5 10
2 1 5
3 1 5
2 1 5
1 1 10
2 1 5
3 1 5
2 1 5

4 5
1 1 3
2 1 2
3 2 3
1 2 1
2 1 4

ans:
0
5
15
17

3



*/