hdu 3308 线段树 区间合并+单点更新+区间查询

LCIS

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6592    Accepted Submission(s): 2866

Problem Description

Given n integers.
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].

Input

T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).

Output

For each Q, output the answer.

Sample Input

1
10 10
7 7 3 3 5 9 9 8 1 8
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9

Sample Output

1
1
4
2
3
1
2
5

Author

shǎ崽

Source

HDOJ Monthly Contest – 2010.02.06

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
const int N=1e5+10,M=4e6+10,inf=1e9+10;
struct is
{
    int l,r;
    int lm,mm,rm;
}tree[N<<2];
int val[N];
void buildtree(int l,int r,int pos)
{
    tree[pos].l=l;
    tree[pos].r=r;
    if(l==r)
    {
        tree[pos].lm=tree[pos].rm=tree[pos].mm=1;
        return;
    }
    int mid=(l+r)>>1;
    buildtree(l,mid,pos<<1);
    buildtree(mid+1,r,pos<<1|1);
    tree[pos].lm=tree[pos<<1].lm;
    tree[pos].rm=tree[pos<<1|1].rm;
    if(val[tree[pos<<1].r]<val[tree[pos<<1|1].l])
    tree[pos].mm=max(tree[pos<<1].mm,max(tree[pos<<1|1].mm,tree[pos<<1].rm+tree[pos<<1|1].lm));
    else
    tree[pos].mm=max(tree[pos<<1].mm,tree[pos<<1|1].mm);
    if(val[tree[pos<<1].r]<val[tree[pos<<1|1].l]&&tree[pos<<1].lm==tree[pos<<1].r-tree[pos<<1].l+1)
    tree[pos].lm+=tree[pos<<1|1].lm;
    if(val[tree[pos<<1].r]<val[tree[pos<<1|1].l]&&tree[pos<<1|1].rm==tree[pos<<1|1].r-tree[pos<<1|1].l+1)
    tree[pos].rm+=tree[pos<<1].rm;
}
void update(int point,int pos)
{
    if(tree[pos].l==tree[pos].r)
    return;
    int mid=(tree[pos].r+tree[pos].l)>>1;
    if(point>mid)
    update(point,pos<<1|1);
    else
    update(point,pos<<1);
    tree[pos].lm=tree[pos<<1].lm;
    tree[pos].rm=tree[pos<<1|1].rm;
    if(val[tree[pos<<1].r]<val[tree[pos<<1|1].l])
    tree[pos].mm=max(tree[pos<<1].mm,max(tree[pos<<1|1].mm,tree[pos<<1].rm+tree[pos<<1|1].lm));
    else
    tree[pos].mm=max(tree[pos<<1].mm,tree[pos<<1|1].mm);
    if(val[tree[pos<<1].r]<val[tree[pos<<1|1].l]&&tree[pos<<1].lm==tree[pos<<1].r-tree[pos<<1].l+1)
    tree[pos].lm+=tree[pos<<1|1].lm;
    if(val[tree[pos<<1].r]<val[tree[pos<<1|1].l]&&tree[pos<<1|1].rm==tree[pos<<1|1].r-tree[pos<<1|1].l+1)
    tree[pos].rm+=tree[pos<<1].rm;
}
is query(int L,int R,int pos)
{
    if(tree[pos].l==L&&tree[pos].r==R)
    return tree[pos];
    int mid=(tree[pos].l+tree[pos].r)>>1;
    if(mid<L)
    return query(L,R,pos<<1|1);
    else if(mid>=R)
    return query(L,R,pos<<1);
    else
    {
        is a=query(L,mid,pos<<1);
        is b=query(mid+1,R,pos<<1|1);
        is ans;
        ans.l=a.l,ans.r=b.r;
        ans.lm=a.lm;
        ans.rm=b.rm;
        if(val[a.r]<val[b.l])
        ans.mm=max(a.mm,max(b.mm,a.rm+b.lm));
        else
        ans.mm=max(a.mm,b.mm);
        if(val[a.r]<val[b.l]&&a.lm==a.r-a.l+1)
        ans.lm+=b.lm;
        if(val[a.r]<val[b.l]&&b.rm==b.r-b.l+1)
        ans.rm+=a.rm;
        return ans;
    }
}
char a[10];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
        buildtree(1,n,1);
        while(m--)
        {
            int l,r;
            scanf("%s%d%d",a,&l,&r);
            l++;
            if(a[0]==‘U‘)
            val[l]=r,update(l,1);
            else
            r++,printf("%d\n",query(l,r,1).mm);
            }
    }
    return 0;
}
时间: 2024-12-28 19:37:24

hdu 3308 线段树 区间合并+单点更新+区间查询的相关文章

hdu 3308(线段树区间合并)

LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6069    Accepted Submission(s): 2635 Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. (index

HDU 3308 LCIS(区间合并 + 单点更新)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意:给定n个数.2种操作. 更新第a个数为b. 查询区间[a,b]的最长连续上升子序列. 思路:裸的区间合并.每个结点存 从区间左端点开始的最长连续上升子序列的长度lm. 以区间右端点结束的最长连续上升子序列的长度rm. 区间的最长连续上升子序列的长度mx. 区间左端点的数值la. 区间右端点的数值ra. 代码: #include <iostream> #include <stdio

hdu 1166 线段树 区间求和 +单点更新 CD模板

题目链接 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 69983    Accepted Submission(s): 29354 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tid

hdu 1754 线段树 水题 单点更新 区间查询

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

HDU 4339 线段树区间合并

Query Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2573    Accepted Submission(s): 851 Problem Description You are given two strings s1[0..l1], s2[0..l2] and Q - number of queries.Your task

HDU 3911 线段树区间合并

北京赛区快了,准备袭击数据结构和图论.倒计时 18天,线段树区间合并.维护一个最长连续.. 题意:给一个01串,以下有一些操作,问区间最长的连续的1的个数 思路:非常裸的线段树区间合并 #include<iostream> #include<cstdio> #include<map> #include<set> #include<cmath> #define lson id << 1 #define rson id <<

hdu 1116 敌兵布阵 线段树 区间求和 单点更新

线段树的基本知识可以先google一下,不是很难理解 线段树功能:update:单点增减 query:区间求和 #include <bits/stdc++.h> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; const int MAXN = 50008; int sum[MAXN<<2]; void build(int l, int r, int rt)

HDU(1166),线段树模板,单点更新,区间总和

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 第一次做线段树,帆哥的一句话,我记下来了,其实,线段树就是一种处理数据查询和更新的手段. 然后,我的代码风格,是网上的大牛们的辛苦总结,我就套用了.这里,我还是简单说一下线段树,说的不好,主要方便自己复习. 线段树,3个步骤,建树,查询,更新, 建树:到底部就是a[]数组的值,建立左右子树后,向上推根,根为左右子树的值 更新:类似建树,二分,找到单点所在区间,更新该区间,记得上一个区间也要变化

HDU 1394:Minimum Inversion Number(线段树区间求和单点更新)

http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. For a given sequence of numbe