Educational Codeforces Round 70 (Rated for Div. 2) C. You Are Given a WASD-string...(线段树)

题目链接

http://codeforces.com/contest/1202/problem/C

题目描述

You have a string ss — a sequence of commands for your toy robot. The robot is placed in some cell of a rectangular grid. He can perform four commands:

  • 'W' — move one cell up;
  • 'S' — move one cell down;
  • 'A' — move one cell left;
  • 'D' — move one cell right.

Let Grid(s) be the grid of minimum possible area such that there is a position in the grid where you can place the robot in such a way that it will not fall from the grid while running the sequence of commands. For example, if s=DSAWWAW then Grid(s) is the 4×3 grid:

  1. you can place the robot in the cell (3,2);
  2. the robot performs the command 'D' and moves to (3,3);
  3. the robot performs the command 'S' and moves to (4,3);
  4. the robot performs the command 'A' and moves to (4,2);
  5. the robot performs the command 'W' and moves to (3,2);
  6. the robot performs the command 'W' and moves to (2,2);
  7. the robot performs the command 'A' and moves to (2,1);
  8. the robot performs the command 'W' and moves to (1,1).

Educational Codeforces Round 70 (Rated for Div. 2) C. You Are Given a WASD-string...(线段树)_第1张图片

You have 44 extra letters: one 'W', one 'A', one 'S', one 'D'. You'd like to insert at most one of these letters in any position of sequence ss to minimize the area of Grid(s).

What is the minimum area of Grid(s) you can achieve?

Input

The first line contains one integer T (1≤T≤1000) — the number of queries.

Next T lines contain queries: one per line. This line contains single string s (1≤|s|≤2⋅10^5, si∈{W,A,S,D}) — the sequence of commands.

It's guaranteed that the total length of s over all queries doesn't exceed 2⋅10^5

Output

Print T integers: one per query. For each query print the minimum area of Grid(s) you can achieve.

Example

input

3
DSAWWAW
D
WA

output

8
2
4

题意

给一个字符串序列包含{W,S,A,D}四个字符,分别表示在某一个初始位置向上下左右移动一个格子。

定义Grid(s)为 i一个包含所有所走位置的最小面积矩形。现在在该字符串上最多插入一个字符,问能构成的最小Grid(s)

思路

将当前位置的横纵坐标分开,分别用两个线段树维护各自的最大值与最小值。如要插入字符则将区间(i+1,n)所有元素加1或减1。

代码虽然很长但大部分都是直接套的模板。

代码

#include
#define ll long long
#define maxn 200010
using namespace std;
ll n;
const ll MAXM=200010;

ll a[MAXM+5],smax[(MAXM<<2)+5],smin[(MAXM<<2)+5],add[(MAXM<<2)+5];
ll b[MAXM+5],smax1[(MAXM<<2)+5],smin1[(MAXM<<2)+5],add1[(MAXM<<2)+5];
void init(){
	ll i,len=n*4+5;
	for(i=0;i>1);
        build(o<<1,l,m);
        build((o<<1)|1,m+1,r);
        smax[o]=max(smax[o<<1],smax[(o<<1)|1]);
        smin[o]=min(smin[o<<1],smin[(o<<1)|1]);
    }
}
void pushup(ll o){
    smin[o]=min(smin[o<<1],smin[(o<<1)|1]);
    smax[o]=max(smax[o<<1],smax[(o<<1)|1]);
}
void pushdown(ll o,ll l,ll r){
    if(add[o]){
        add[o<<1]+=add[o];
        add[o<<1|1]+=add[o];
        smin[o<<1]+=add[o];
        smin[o<<1|1]+=add[o];
        smax[o<<1]+=add[o];
        smax[o<<1|1]+=add[o];
        add[o]=0;
    }
}
void update(ll o,ll l,ll r,ll ql,ll qr,ll addv){
    if(ql<=l&&qr>=r){
        add[o]+=addv;
        smin[o]+=addv;
        smax[o]+=addv;
        return;
    }
    pushdown(o,l,r);
    ll m=l+((r-l)>>1);
    if(ql<=m)update(o<<1,l,m,ql,qr,addv);
    if(qr>=m+1)update(o<<1|1,m+1,r,ql,qr,addv);
    pushup(o);
}
ll query_max(ll o,ll l,ll r,ll ql,ll qr){
    if(ql<=l&&qr>=r) return smax[o];
    pushdown(o,l,r);
    ll m=l+((r-l)>>1);
    ll ans=0;
    if(ql<=m)ans=query_max(o<<1,l,m,ql,qr);
    if(qr>=m+1)ans=max(ans,query_max(o<<1|1,m+1,r,ql,qr));
	return ans; 
}
ll query_min(ll o,ll l,ll r,ll ql,ll qr){
    if(ql<=l&&qr>=r) return smin[o];
    pushdown(o,l,r);
    ll m=l+((r-l)>>1);
    ll ans=0;
    if(ql<=m)ans=query_min(o<<1,l,m,ql,qr);
    if(qr>=m+1)ans=min(ans,query_min(o<<1|1,m+1,r,ql,qr));
	return ans; 
}

void build1(ll o,ll l,ll r){
    if(l==r)smin1[o]=smax1[o]=b[l];
    else{
        ll m=l+((r-l)>>1);
        build1(o<<1,l,m);
        build1((o<<1)|1,m+1,r);
        smax1[o]=max(smax1[o<<1],smax1[(o<<1)|1]);
        smin1[o]=min(smin1[o<<1],smin1[(o<<1)|1]);
    }
}
void pushup1(ll o){
    smin1[o]=min(smin1[o<<1],smin1[(o<<1)|1]);
    smax1[o]=max(smax1[o<<1],smax1[(o<<1)|1]);
}
void pushdown1(ll o,ll l,ll r){
    if(add1[o]){
        add1[o<<1]+=add1[o];
        add1[o<<1|1]+=add1[o];
        smin1[o<<1]+=add1[o];
        smin1[o<<1|1]+=add1[o];
        smax1[o<<1]+=add1[o];
        smax1[o<<1|1]+=add1[o];
        add1[o]=0;
    }
}

void update1(ll o,ll l,ll r,ll ql,ll qr,ll add1v){
    if(ql<=l&&qr>=r){
        add1[o]+=add1v;
        smin1[o]+=add1v;
        smax1[o]+=add1v;
        return;
    }
    pushdown1(o,l,r);
    ll m=l+((r-l)>>1);
    if(ql<=m)update1(o<<1,l,m,ql,qr,add1v);
    if(qr>=m+1)update1(o<<1|1,m+1,r,ql,qr,add1v);
    pushup1(o);
}
ll query_max1(ll o,ll l,ll r,ll ql,ll qr){
    if(ql<=l&&qr>=r) return smax1[o];
    pushdown1(o,l,r);
    ll m=l+((r-l)>>1);
    ll ans=0;
    if(ql<=m)ans=query_max1(o<<1,l,m,ql,qr);
    if(qr>=m+1)ans=max(ans,query_max1(o<<1|1,m+1,r,ql,qr));
	return ans; 
}
ll query_min1(ll o,ll l,ll r,ll ql,ll qr){
    if(ql<=l&&qr>=r) return smin1[o];
    pushdown1(o,l,r);
    ll m=l+((r-l)>>1);
    ll ans=0;
    if(ql<=m)ans=query_min1(o<<1,l,m,ql,qr);
    if(qr>=m+1)ans=min(ans,query_min1(o<<1|1,m+1,r,ql,qr));
	return ans; 
}
char s[maxn];
int main(){
	ll t,i;
	cin>>t;
	memset(smax,0,sizeof(smax));
	memset(smin,0,sizeof(smin));
	memset(add,0,sizeof(add));
	memset(smax1,0,sizeof(smax1));
	memset(smin1,0,sizeof(smin1));
	memset(add1,0,sizeof(add1));	
	while(t--){
		scanf("%s",s);
		n=strlen(s)+1;	
		a[1]=b[1]=0;
		for(i=0;iar)ar=a[i]+1;
			bl=sbl;
			br=sbr;
			ans=min(ans,(ar-al+1)*(br-bl+1));
			update(1,1,n,i+1,n,-2);
			al=query_min(1,1,n,1,n);
			ar=query_max(1,1,n,1,n);
			if(a[i]-1br)br=b[i]+1;
			ans=min(ans,(ar-al+1)*(br-bl+1));
			update1(1,1,n,i+1,n,-2);
			bl=query_min1(1,1,n,1,n);
			br=query_max1(1,1,n,1,n);
			if(b[i]-1

 

你可能感兴趣的:(线段树)