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

*/

HDU 4893 Wow! Such Sequence! 水线段树,布布扣,bubuko.com

时间: 2024-11-05 02:24:51

HDU 4893 Wow! Such Sequence! 水线段树的相关文章

hdu 4893 Wow! Such Sequence!(线段树功能:单点更新,区间更新相邻较小斐波那契数)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 --------------------------------------------------------------------------------------------------------------------------------------------

HDU 4893 Wow! Such Sequence! (线段树)

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 838    Accepted Submission(s): 245 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

hdu 4893 Wow! Such Sequence!(线段树)

题目链接:hdu 4983 Wow! Such Sequence! 题目大意:就是三种操作 1 k d, 修改k的为值增加d 2 l r, 查询l到r的区间和 3 l r, 间l到r区间上的所以数变成最近的斐波那契数,相等的话取向下取. 解题思路:线段树,对于每个节点新增一个bool表示该节点以下的位置是否都是斐波那契数. #include <cstdio> #include <cstring> #include <cstdlib> #include <algor

线段树 + 区间更新: HDU 4893 Wow! Such Sequence!

Wow! Such Sequence! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2234    Accepted Submission(s): 657 Problem Description Recently, Doge got a funny birthday present from his new friend, Prot

Wow! Such Sequence! (线段树) hdu4893

http://acm.hdu.edu.cn/showproblem.php?pid=4893 先贴上一份还没过的代码,不知道拿出错了  1 // by caonima 2 // hehe  3 #include <cstring>  4 #include <algorithm>  5 #include <cstdio>  6 #include <queue>  7 #include <stack>  8 #include <vector&g

HDU 1754 I Hate It 水线段树

点击打开链接 I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 37367    Accepted Submission(s): 14775 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是

hdu 4893 Wow! Such Sequence!

http://acm.hdu.edu.cn/showproblem.php?pid=4893 三种操作: 1 k d - "add" 2 l r - "query sum" 3 l r - "change to nearest Fibonacci" 节点附件三个值: s1:由lazy控制的区间的正确的和. s2:区间内与所有数相近的fib数之和,随着单点更新而更新. col:lazy,标记区间是否全部取fib数,是取1,否则取0. 询问区间的和时

HDU 4893 Wow! Such Sequence 线段树暴力

题意:n个数 初始为0,三个操作:给某个数加上d,查询区间和,把区间[l,r]中每个a[i]变为离a[i]最近的斐波那契数,n,m<=1e5. 无操作1情况下,每个点最多变化一次,每次修改logn,算上操作1 最坏情况下修改n+m次 O((n+m)logn). 对区间设个标记 线段树暴力即可. #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; const int

HDU 4893 Wow! Such Sequence!(2014年多校联合 第三场 G)(线段树)

磨了一天的线段树,不能说完全搞清楚,只能说有一个大概的了解,靠着模板才把这道题A了,只能说太弱~~! 题意: 初始时有一字符串,全为0. 三种操作: 1 k d - add  把d加到第k个数上去2 l r - query sum 计算l到r所有数的和3 l r - change to nearest Fibonacci 把l到r的数修改为距离它最近的斐波那契数 节点附件三个值: s1:由lazy控制的区间的正确的和. s2:区间内与所有数相近的fib数之和,随着单点更新而更新. col:laz