2014多校3 Wow! Such Sequence!线段树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893

这题实在是让人纠结啊……好久不写线段树的题了,因为这几天学伸展树,然后觉得线段树小case了。没想到栽在这题上了。尼玛……

自己把自己给搞晕了……想复杂了,都不懂得预处理一下,唉……还得怒刷几十道啊!!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define MM 500015
#define INF 0x7fffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define eps 1e-8
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
typedef long long ll;
typedef unsigned long long ULL;
using namespace std;
long long Fib[91],sum[MM],fib[MM];
int val[MM];
int n;
void init()
{
    Fib[0]=1;
    Fib[1]=1;
    for(int i=2; i<92; i++)
        Fib[i]=Fib[i-1]+Fib[i-2];
}
void pushUp(int i)
{
    sum[i]=sum[i<<1]+sum[i<<1|1];
    fib[i]=fib[i<<1]+fib[i<<1|1];
}
void pushDown(int i)
{
    if(val[i])
    {
        val[i<<1]=1,val[i<<1|1]=1;
        sum[i<<1]=fib[i<<1],sum[i<<1|1]=fib[i<<1|1];
        val[i]=0;
    }
}
void update(int i,int l,int r,int L,int v)
{
    if(l==r&&l==L)
    {
        sum[i]+=v;
        if(sum[i]<=1) {fib[i]=1;return;}
        int ii=lower_bound(Fib,Fib+92,sum[i])-Fib;
        if(Fib[ii]-sum[i]>=sum[i]-Fib[ii-1])
            fib[i]=Fib[ii-1];
        else fib[i]=Fib[ii];
        return ;
    }
    int mid=(l+r)>>1;
    pushDown(i);
    if(L>mid) update(rson,L,v);
    else update(lson,L,v);
    pushUp(i);
}
void update1(int i,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)
    {
        sum[i]=fib[i];
        val[i]=1;
        return ;
    }
    int mid=(l+r)>>1;
    pushDown(i);
    if(R>mid) update1(rson,L,R);
    if(L<=mid) update1(lson,L,R);
    pushUp(i);
}
ll query(int i,int l,int r,int L,int R)
{
    if(L<=l&&r<=R) return sum[i];
    ll ans=0;
    int mid=(l+r)>>1;
    pushDown(i);
    if(R>mid) ans+=query(rson,L,R);
    if(L<=mid) ans+=query(lson,L,R);
    return ans;
}
void build(int i,int l,int r)
{
    if(l==r)
    {
        sum[i]=val[i]=0;
        fib[i]=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);build(rson);
    pushUp(i);
    val[i]=0;
}
int main()
{
    int m;
    init();
    while(~scanf("%d%d",&n,&m))
    {
        build(1,1,n);
        while(m--)
        {
            int a,l,r;
            scanf("%d%d%d",&a,&l,&r);
            if(a==1) update(1,1,n,l,r);
            else if(a==2) printf("%I64d\n",query(1,1,n,l,r));
            else if(a==3) update1(1,1,n,l,r);
        }
    }
    return 0;
}

2014多校3 Wow! Such Sequence!线段树

时间: 2024-10-24 22:19:26

2014多校3 Wow! Such Sequence!线段树的相关文章

hdu 4893 (多校1007)Wow! Such Sequence!(线段树&amp;二分&amp;思维)

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

2014多校3 Wow! Such Sequence!段树

主题链接:http://acm.hdu.edu.cn/showproblem.php? pid=4893 这个问题还真是纠结啊--好久不写线段树的题了.由于这几天学伸展树.然后认为线段树小case了.没想到栽在这题上了.尼玛-- 自己把自己给搞晕了--想复杂了.都不懂得预处理一下,唉--还得怒刷几十道啊! ! #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #

HDU4893 Wow! Such Sequence! 线段树

题意:给你一个序列,其中有三种操作 1)位置为K 的数+ D 2)求 l-r 区间和 3)把 l-r 区间里面的所有数都变为理它最近的斐波纳契数 解题思路:这个题的区间更新其实可以在单点更新的时候就得出,为节点维护两个 和,一个是 斐波纳契和 一个是正常和 ,再看这个区间有没有被3覆盖,特判一下就行了. 解题代码: 1 // File Name: 1007.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月29日 星期二 12时49分33

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

HDOJ 4893 Wow! Such Sequence! 线段树

http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:10万的区间,初始都为0,10万次操作,三种操作为单点修改,区间将每个数改成最近的斐波那契数,以及区间求和. 分析:用一个flag记录该段是否被改成斐波那契数,同时多维护一个sum1表示如果该段改成斐波那契数,区间和为多少.开始sum1为区间长度,之后在单点做了修改以后对其更新,需要的时候用其覆盖sum. 1 #include<cstdio> 2 #include<cstring>

HDU4893:Wow! Such Sequence!(线段树lazy)

Problem Description Recently, Doge got a funny birthday present from his new friend, Protein Tiger from St. Beeze College. No, not cactuses. It's a mysterious blackbox. After some research, Doge found that the box is maintaining a sequence an of n nu

2016暑假多校联合---Rikka with Sequence (线段树)

2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them: Yuta has an array A with n numbers. Then he make

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多校第三场-J】

题意:一个初始为0的数组,支持三种操作:1.向第k个数添加d,(|d| < 2^31);2.把[l, r]区间内的数字都换成与它最相近的Fibonacci数;3.询问[l, r]区间的和. 思路:初始化Fibonacci数组,longlong 类型内90个就够用了. 线段树区间查询,用lazy标记, sgt[]记录线段树各个节点的区间和, fib_num_sum[]记录与各个叶子节点当前值最接近的Fibonacci数,传递到区间fib_num_sum[]就是区间Fibonacci数的和. 操作1