【HDU5306】【DTOJ2481】Gorgeous Sequence【线段树】

待填坑

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#define ll long long
using namespace std;
int T,n,m;
ll a[1000001];
class Segtree
{
public:
    ll sum[1000001*5],mx[1000001*5],smx[1000001*5],cnt[1000001*5],fl[1000001*5];

    void pushup(int pos)
    {
        sum[pos]=sum[pos<<1]+sum[pos<<1|1];
        if(mx[pos<<1]>mx[pos<<1|1])
        {
          mx[pos]=mx[pos<<1];
          cnt[pos]=cnt[pos<<1];
          if(mx[pos<<1|1]>smx[pos<<1])smx[pos]=mx[pos<<1|1];
          else smx[pos]=smx[pos<<1];
        }
        if(mx[pos<<1]<mx[pos<<1|1])
        {
          mx[pos]=mx[pos<<1|1];
          cnt[pos]=cnt[pos<<1|1];
          if(mx[pos<<1]>smx[pos<<1|1])smx[pos]=mx[pos<<1];
          else smx[pos]=smx[pos<<1|1];
        }
        if(mx[pos<<1]==mx[pos<<1|1])
        {
          mx[pos]=mx[pos<<1];
          cnt[pos]=cnt[pos<<1]+cnt[pos<<1|1];
          if(smx[pos<<1]>smx[pos<<1|1])smx[pos]=smx[pos<<1];
          else smx[pos]=smx[pos<<1|1];
        }
    }
    void pushdown(int pos)
    {
        if(fl[pos]>=0)
        {
          if(mx[pos<<1]>fl[pos])
          {
            sum[pos<<1]-=(mx[pos<<1]-fl[pos])*cnt[pos<<1];
            fl[pos<<1]=mx[pos<<1]=fl[pos];
          }
          if(mx[pos<<1|1]>fl[pos])
          {
            sum[pos<<1|1]-=(mx[pos<<1|1]-fl[pos])*cnt[pos<<1|1];
            fl[pos<<1|1]=mx[pos<<1|1]=fl[pos];
          }
          fl[pos]=-1;
        }
    }
    void build(int l,int r,int pos)
    {
        if(l==r)
        {
          sum[pos]=mx[pos]=a[l];
          cnt[pos]=1;
          fl[pos]=smx[pos]=-1;
          return;
        }
        int mid=l+r>>1;
        build(l,mid,pos<<1);
        build(mid+1,r,pos<<1|1);
        pushup(pos);
        fl[pos]=-1;
    }
    void change(int l,int r,int al,int ar,ll v,int pos)
    {
        int mid=l+r>>1;
        if(l==al && r==ar)
        {
          if(v>=mx[pos])return;
          if(smx[pos]<v && v<mx[pos])
          {
              sum[pos]-=(mx[pos]-v)*cnt[pos];
              fl[pos]=mx[pos]=v;
              return;
          }
          change(l,mid,al,mid,v,pos<<1);
          change(mid+1,r,mid+1,ar,v,pos<<1|1);
          pushup(pos);
          return;
        }
        pushdown(pos);
        if(ar<=mid)change(l,mid,al,ar,v,pos<<1);
        if(al>mid)change(mid+1,r,al,ar,v,pos<<1|1);
        if(al<=mid && ar>mid){change(l,mid,al,mid,v,pos<<1);change(mid+1,r,mid+1,ar,v,pos<<1|1);}
        pushup(pos);
    }
    ll askmax(int l,int r,int al,int ar,int pos)
    {
        if(l==al && r==ar)return mx[pos];
        int mid=l+r>>1;
        pushdown(pos);
        if(ar<=mid)return askmax(l,mid,al,ar,pos<<1);
        if(al>mid)return askmax(mid+1,r,al,ar,pos<<1|1);
        if(al<=mid && ar>mid)
        {
          ll t1=askmax(l,mid,al,mid,pos<<1),t2=askmax(mid+1,r,mid+1,ar,pos<<1|1);
          return t1>t2?t1:t2;
        }
    }
    ll asksum(int l,int r,int al,int ar,int pos)
    {
        if(l==al && r==ar)return sum[pos];
        int mid=l+r>>1;
        pushdown(pos);
        if(ar<=mid)return asksum(l,mid,al,ar,pos<<1);
        if(al>mid)return asksum(mid+1,r,al,ar,pos<<1|1);
        if(al<=mid && ar>mid)return asksum(l,mid,al,mid,pos<<1)+asksum(mid+1,r,mid+1,ar,pos<<1|1);
    }
}segtree;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
      scanf("%d%d",&n,&m);
      for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
      segtree.build(1,n,1);
      int mod,x,y;ll t;
      while(m--)
      {
        scanf("%d",&mod);
        if(mod==0)
        {
          scanf("%d%d%lld",&x,&y,&t);
          segtree.change(1,n,x,y,t,1);
        }
        if(mod==1)
        {
          scanf("%d%d",&x,&y);
          printf("%lld\n",segtree.askmax(1,n,x,y,1));
        }
        if(mod==2)
        {
          scanf("%d%d",&x,&y);
          printf("%lld\n",segtree.asksum(1,n,x,y,1));
        }
      }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/worcher/p/11561073.html

时间: 2024-11-17 03:44:07

【HDU5306】【DTOJ2481】Gorgeous Sequence【线段树】的相关文章

【hdu5306】Gorgeous Sequence 线段树区间最值操作

题目描述 给你一个序列,支持三种操作: $0\ x\ y\ t$ :将 $[x,y]$ 内大于 $t$ 的数变为 $t$ :$1\ x\ y$ :求 $[x,y]$ 内所有数的最大值:$2\ x\ y$ :求 $[x,y]$ 内所有数的和. 多组测试数据,$\sum n,\sum m\le 10^6$ 题解 线段树区间最值操作 对于线段树上的一个节点,维护对应区间的:最大值 $mx$ .最大值个数 $c$ 及严格次大值 $se$ .那么对于一次区间最小值操作: 如果 $t\ge mx$ ,则这个

HDU 5306 Gorgeous Sequence[线段树区间最值操作]

Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2150    Accepted Submission(s): 594 Problem Description There is a sequence a of length n. We use ai to denote the i-th elemen

HDOJ 5306 Gorgeous Sequence 线段树

http://www.shuizilong.com/house/archives/hdu-5306-gorgeous-sequence/ Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 440    Accepted Submission(s): 87 Problem Description Th

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 (多校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

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! 线段树

题意:给你一个序列,其中有三种操作 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!-线段树【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

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

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

CF(438D) The Child and Sequence(线段树)

题意:对数列有三种操作: Print operation l,?r. Picks should write down the value of . Modulo operation l,?r,?x. Picks should perform assignment a[i]?=?a[i] mod x for each i (l?≤?i?≤?r). Set operation k,?x. Picks should set the value of a[k] to x (in other words