njust 1420-線段樹-3

http://icpc.njust.edu.cn/Problem/Show/1420?Title=Easy_task_

題意:給一個字符串,很多操作

Q L R : output the length of the longest consecutive non-decreasing subsequence

C L R P : replace each letter from L to R by letter P('a'<=P<='z') 。



分析:很明顯要用線段樹做,基本做法就如最長連續的0或1的個數的做法一樣,記錄區間的邊界,每次兩區間合併時比較相鄰兩元素即可。。。

代碼:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

#define N 100010
int n, m;
char s[N], s1[3];

struct node
{
    int l, r, mid;
    int max, lmax, rmax;
    char lazy, lc, rc;
}a[N*4];

inline int max(int a, int b)
{
    return a>b ? a : b;
}
inline int min(int a ,int b)
{
    return a<b ? a : b;
}

inline void up(int p)
{
    a[p].lc = a[p*2].lc;
    a[p].rc = a[p*2+1].rc;
    a[p].lmax = a[p*2].lmax;
    a[p].rmax = a[p*2+1].rmax;
    a[p].max = max(a[p*2].max, a[p*2+1].max);
    if(a[p*2].rc<=a[p*2+1].lc)
    {
        a[p].max = max(a[p].max, a[p*2].rmax+a[p*2+1].lmax);
        if(a[p*2].rmax==a[p*2].r-a[p*2].l+1)
        {
            a[p].lmax += a[p*2+1].lmax;
        }
        if(a[p*2+1].lmax==a[p*2+1].r-a[p*2+1].l+1)
        {
            a[p].rmax += a[p*2].rmax;
        }
    }
}

void build(int l, int r, int p)
{
    a[p].l = l;
    a[p].r = r;
    a[p].mid = (a[p].l+a[p].r)/2;
    a[p].lazy = 0;
    if(a[p].l==a[p].r)
    {
        a[p].lc = a[p].rc = s[l];
        a[p].max = a[p].lmax = a[p].rmax = 1;
        return;
    }
    build(l, a[p].mid, p*2);
    build(a[p].mid+1, r, p*2+1);
    up(p);
}

inline void down(int p)
{
    a[p*2].lazy = a[p*2].lc = a[p*2].rc = a[p].lazy;
    a[p*2].max = a[p*2].lmax = a[p*2].rmax = a[p*2].r-a[p*2].l+1;
    a[p*2+1].lazy = a[p*2+1].lc = a[p*2+1].rc = a[p].lazy;
    a[p*2+1].max = a[p*2+1].lmax = a[p*2+1].rmax = a[p*2+1].r-a[p*2+1].l+1;
    a[p].lazy = 0;
}

void update(int l, int r, int p)
{
    if(a[p].l==l && a[p].r==r)
    {
        a[p].lazy = s1[0];
        a[p].max = a[p].lmax = a[p].rmax = a[p].r-a[p].l+1;
        a[p].lc = a[p].rc = a[p].lazy;
        return;
    }

    if(a[p].lazy!=0)
    {
        down(p);
    }
    if(r<=a[p].mid)
    {
        update(l, r, p*2);
    }
    else if(l>a[p].mid)
    {
        update(l, r, p*2+1);
    }
    else
    {
        update(l, a[p].mid, p*2);
        update(a[p].mid+1, r, p*2+1);
    }
    up(p);
}

int query(int l, int r, int p)
{
    if(l==a[p].l && r==a[p].r)
    {
        return a[p].max;
    }

    if(a[p].lazy!=0)
    {
        down(p);
    }
    int ans;
    if(r<=a[p].mid)
    {
        ans = query(l, r, p*2);
    }
    else if(l>a[p].mid)
    {
        ans = query(l, r, p*2+1);
    }
    else
    {
        ans = max( query(l, a[p].mid, p*2), query(a[p].mid+1, r, p*2+1) );
        if(a[p*2].rc<=a[p*2+1].lc)
        {
            ans = max( ans, min(a[p*2].rmax, a[p*2].r-l+1) + min(a[p*2+1].lmax, r-a[p*2+1].l+1) );
        }
    }
    //up(p);
    return ans;
}

int main()
{
    //freopen("Easy task.in", "r", stdin);
    //freopen("Easy task1.out", "w", stdout);
    int i, j, k, cas;
    scanf("%d", &cas);
    while(cas--)
    {
        scanf("%s", s+1);
        n = strlen(s+1);
        build(1, n, 1);
        scanf("%d", &m);
        while(m--)
        {
            scanf("%s", s1);
            if(s1[0]=='C')
            {
               scanf("%d %d %s", &j, &k, s1);
               if(j>k)
               {
                   swap(j, k);
               }
               update(j, k, 1);
            }
            else
            {
                scanf("%d %d", &j, &k);
                if(j>k)
                {
                    swap(j, k);
                }
                printf("%d\n", query(j, k, 1));
            }
        }
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章