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 N=2e6+5;
struct node{
    int l,r;
    int mid(){return l+r>>1;}
    ll flag,sum;
}t[N>>2];
int n,m;
ll f[200];
ll calc(ll x)
{
    ll mn=1e18,res;
    for(int i=1;i<=90;i++)
    {
        if(mn>abs(f[i]-x))
            mn=abs(f[i]-x),res=f[i];
    }
    return res;
}
void push_up(int rt)
{
    t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
    t[rt].flag=t[rt<<1].flag & t[rt<<1|1].flag;
}
void build(int rt,int l,int r)
{
    t[rt].l=l,t[rt].r=r;
    if(l==r)
    {
        t[rt].sum=0;
        t[rt].flag=0;
        return;
    }
    int m=t[rt].mid();
    build(rt<<1,l,m);
    build(rt<<1|1,m+1,r);
    push_up(rt);
}
void setval(int rt,int pos,int d)
{
    int l=t[rt].l,r=t[rt].r;
    if(l==r)
    {
        t[rt].sum+=d;
        t[rt].flag=0;
        return;
    }
    int m=t[rt].mid();
    if(pos<=m)
        setval(rt<<1,pos,d);
    else
        setval(rt<<1|1,pos,d);
    push_up(rt);
}
ll query(int rt,int ql,int qr)
{
    int l=t[rt].l,r=t[rt].r;
    if(ql<=l&&qr>=r)
        return t[rt].sum;
    ll m=t[rt].mid(),res=0;
    if(ql<=m)
        res+=query(rt<<1,ql,qr);
    if(qr>m)
        res+=query(rt<<1|1,ql,qr);
    return res;
}
void update(int rt,int ql,int qr)
{
    int l=t[rt].l,r=t[rt].r;
    if(ql<=l&&qr>=r && (t[rt].flag))
        return;
    if(l==r)
    {
        t[rt].sum=calc(t[rt].sum);
        t[rt].flag=1;
        return;
    }
    int m=t[rt].mid();
    if(ql<=m)
        update(rt<<1,ql,qr);
    if(qr>m)
        update(rt<<1|1,ql,qr);
    push_up(rt);
}
int main()
{
    f[0]=f[1]=1;
    for(int i=1;i<=90;i++)
        f[i]=f[i-1]+f[i-2];
    while(cin>>n>>m)
    {
        build(1,1,n);
        int op,k,d,l,r;
        while(m--)
        {
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d%d",&k,&d);
                setval(1,k,d);
            }
            else
            {
                scanf("%d%d",&l,&r);
                if(op==2)
                    printf("%I64d\n",query(1,l,r));
                else
                    update(1,l,r);
            }
        }
    }
    return 0;
}

不能直接一整个区间更新,因为有大量不必要的更新操作,算出每个点最多更新多少次,暴力单点

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

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

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>

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

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&l

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!

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

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

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

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