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