njust 1420-线段树-3

来源:互联网 发布:linux开机自启动设置 编辑:程序博客网 时间:2024/06/05 18:44

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 100010int 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;}


原创粉丝点击