HDU 5306 Gorgeous Sequence

参考

关键是加一个标记cv:这个区间有多少个结点,已被 tag 影响。

Gorgeous Sequence

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 396    Accepted Submission(s): 78

Problem Description

There is a sequence a of
length n.
We use ai to
denote the i-th
element in this sequence. You should do the following three types of operations to this sequence.

0 x y t:
For every x≤i≤y,
we use min(ai,t) to
replace the original ai‘s
value.

1 x y:
Print the maximum value of ai that x≤i≤y.

2 x y:
Print the sum of ai that x≤i≤y.

Input

The first line of the input is a single integer T,
indicating the number of testcases.

The first line contains two integers n and m denoting
the length of the sequence and the number of operations.

The second line contains n separated
integers a1,…,an (?1≤i≤n,0≤ai<231).

Each of the following m lines
represents one operation (1≤x≤y≤n,0≤t<231).

It is guaranteed that T=100, ∑n≤1000000, ∑m≤1000000.

Output

For every operation of type 1 or 2,
print one line containing the answer to the corresponding query.

Sample Input

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

Sample Output

5
15
3
12

Hint

Please use efficient IO method

Source

2015 Multi-University Training Contest 2

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define prt(k) cout<<#k" = "<<k<<" ";
const int N = 1000003<<2;
struct Node
{
    int l, r;
    int mx;
    ll ss;
    int tag;
    int cv; /// How many nodes are infected by tag in subtree
} T[N] ;
int a[N];
#define lx x<<1
#define rx x<<1|1
#define lo o<<1
#define ro o<<1|1
/// cv:这个区间有多少个结点,已被 tag 影响。

void pushup(int x)
{
    T[x].ss = T[lx].ss + T[rx].ss;
    T[x].mx = max(T[lx].mx, T[rx].mx);
    T[x].cv = T[lx].cv + T[rx].cv;
}
void mark(int x, int t)  /// da biao ji
{
    if (T[x].tag!=0 && T[x].tag <= t) return ;

    T[x].tag = t;
    int l = T[x].l, r = T[x].r;
    if (T[x].cv != r - l + 1)
    {
        T[x].mx = t;
        T[x].ss += 1ll * (r - l + 1 - T[x].cv) * t;
        T[x].cv = r - l + 1;
    }
}
void pushdown(int x)
{
    if (T[x].tag==0) return;
    mark(lx, T[x].tag);
    mark(rx, T[x].tag);
}
void fix(int o, int t )
{
    if (T[o].mx < t) return;
    if (T[o].tag >= t)
    {
        T[o].tag = 0;  ///
    }
    if (T[o].l==T[o].r)
    {
        T[o].ss = T[o].mx = T[o].tag;
        T[o].cv = T[o].tag != 0;
    }
    else
    {
        pushdown(o);
        fix(lo, t);
        fix(ro, t);
        pushup(o);
    }
}
void update(int o, int t , int L, int R)
{
    if (T[o].mx <= t) return;
    if (R < T[o].l || T[o].r < L ) return;

    if (L<=T[o].l && T[o].r<=R)
    {
        fix(o, t);
        if (T[o].l == T[o].r)
        {
            T[o].ss = T[o].mx=  T[o].tag = t;
            T[o].cv = 1;
        }
        else
        {
            pushup(o);
        }
        mark(o, t);
    }
    else
    {
        pushdown(o);
        update(o<<1, t, L, R);
        update(o<<1|1, t, L, R);
        pushup(o);
    }
}

void build(int o, int l, int  r)
{
    T[o].l = l;
    T[o].r = r;
    if (l==r)
    {
        T[o].ss = T[o].mx = T[o].tag = a[l];
        T[o].cv = 1;
        return;
    }
    int m = (l + r) >> 1;
    T[o].tag = 0;
    build(lo, l, m);
    build(ro, m+1, r);
    pushup(o);
}
Node query(int o, int L, int R)
{
    Node ret ;
    if (L > T[o].r || R < T[o].l)
    {
        ret.mx = ret.ss = 0;
        return ret;
    }
    if (L<=T[o].l && T[o].r <= R) return T[o];
    pushdown(o);
    Node a = query(lo, L, R);
    Node b = query(ro, L, R);
    ret.mx = max(a.mx, b.mx);
    ret.ss = a.ss + b.ss;
    return ret;
}
/************Read**********/
char *ch, *ch1, buf[40*1024000+5], buf1[40*1024000+5];

void read(int &x)
{
    for (++ch; *ch <= 32; ++ch);
    for (x = 0; '0' <= *ch; ch++)    x = x * 10 + *ch - '0';
}

/**************************/
int n, m;
int main()
{
    ch = buf - 1;
    ch1 = buf1 - 1;
    fread(buf, 1, 1000 * 35 * 1024, stdin);
    int re;
    read(re);
    while (re--)
    {
        read(n);
        read(m);
        for (int i = 1; i <= n; i++)
            read(a[i]);

        build(1 ,  1, n);

        while (m--)
        {
            int t, x, y, z;
            read(t);
            read(x);
            read(y);
            if (!t)
            {
                read(z);
                update(1, z, x, y);

            }
            else if (t == 1) printf("%d\n", query(1, x, y).mx);
            else printf("%I64d\n", query(1, x, y).ss);

        }
    }
    return 0;
}
/**
1
5 5
1 2 3 4 5
1 1 5
2 1 5
0 3 5 3
1 1 5
2 1 5
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-02 10:48:54

HDU 5306 Gorgeous Sequence的相关文章

hdu 5306 Gorgeous Sequence(区间最值更新+求和)

题目链接:hdu 5306 Gorgeous Sequence 题意: 给你一个序列,有三种操作. 0 x y t:将[x,y]的数取min(a[i],t) 1 x y:求[x,y]的最大值 2 x y:求[x,y]的区间和 题解: 吉老师的课件题:传送门 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 #define ls l,m,rt<<1 4 #define rs m+1,r,rt

hdu 5306 Gorgeous Sequence(线段树)

题目链接:hdu 5306 Gorgeous Sequence 和普通的线段树一样一个标记值T,然后另外加一个C值记录以u为根节点的子树下有多少个叶子节点被T值控制.每次修改时,dfs到叶子节点之后在修改该节点.维护sum值时只要额外加上T值控制下的节点.加了个输入外挂,时间少了将近1000ms. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const in

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

hdu 5306 Gorgeous Sequence(暴力线段树)(好题)

题意:区间最大长度为1000000, 三种操作: 区间求和: 区间求最大值: 将节点值更新为当前值与给定值中的最小值(有趣的更新): 思路: 暴力线段树.关键在于处理标记,需要维护最大标记,标记覆盖范围,所在区间: 覆盖区域标记起到很关键的作用: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node{ long long sum; int tag,m

【模板】吉司机线段树 HDU 5306 Gorgeous Sequence

也叫小清新线段树,用于解决区间最值修改问题 具体可以参考jiry_2神犇的集训队论文和WC2016上的PPT 此题就作为模板好了,模板的话写法是比较精妙的 #include<bits/stdc++.h> using namespace std; #define go(i,a,b) for(int i=a;i<=b;++i) #define com(i,a,b) for(int i=a;i>=b;--i) #define mem(a,b) memset(a,b,sizeof(a))

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 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ

hdu 4441 Queue Sequence(splay)

题目链接:hdu 4441 Queue Sequence 这题看了题解写的,题解传送门 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 #define ls l,m,rt<<1 4 #define rs m+1,r,rt<<1|1 5 using namespace std; 6 typedef long long ll; 7 8 const int N=1e6+7; 9 i

hdu 5297 Y sequence(容斥)

题目链接:hdu 5297 Y sequence 考虑62以内的指数,x为奇数个质数因子,就减掉,偶数个加上.计算x为指数的不满足数直接pow(n,1/x)即可. #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <algorithm> using namespace std; type