The academic year has just begun, but lessons and olympiads have already occupied all the free time. It is not a surprise that today Olga fell asleep on the Literature. She had a dream in which she was on a stairs.
The stairs consists of n steps. The steps are numbered from bottom to top, it means that the lowest step has number1, and the highest step has number n. Above each of them there is a pointer with the direction (up or down) Olga should move from this step. As soon as Olga goes to the next step, the direction of the pointer (above the step she leaves) changes. It means that the direction "up" changes to "down", the direction "down" — to the direction "up".
Olga always moves to the next step in the direction which is shown on the pointer above the step.
If Olga moves beyond the stairs, she will fall and wake up. Moving beyond the stairs is a moving down from the first step or moving up from the last one (it means then-th) step.
In one second Olga moves one step up or down according to the direction of the pointer which is located above the step on which Olga had been at the beginning of the second.
For each step find the duration of the dream if Olga was at this step at the beginning of the dream.
Olga's fall also takes one second, so if she was on the first step and went down, she would wake up in the next second.
The first line contains single integer n (1 ≤ n ≤ 106) — the number of steps on the stairs.
The second line contains a string s with the lengthn — it denotes the initial direction of pointers on the stairs. Thei-th character of string s denotes the direction of the pointer above i-th step, and is either 'U' (it means that this pointer is directed up), or 'D' (it means this pointed is directed down).
The pointers are given in order from bottom to top.
Print n numbers, the i-th of which is equal either to the duration of Olga's dream or to - 1 if Olga never goes beyond the stairs, if in the beginning of sleep she was on thei-th step.
3 UUD
5 6 3
10 UUDUDUUDDU
5 12 23 34 36 27 18 11 6 1
题目大意:
给你一个长度为N台阶,对应一个位子是U,那么主人公就向上走一步,否则向下走。
对应一个位子走完之后,字符翻转,u变成d,d变成u,问每个位子作为起点,走出这N个台阶需要的步数(上边或者下边都算走了出去)。
思路:
1、如果暴力模拟的话,我们的过程其实就是两种操作:
①如果当前位子是U,那么在其右边找第一个D,如果没有了,就走了出去。
②如果当前位子是D,那么在其左边找到第一个U,如果没有了,就走了出去。
对应当前位子开始模拟,不断的找并且维护过程字符变换。
时间复杂度很高,肯定不能直接这么做。
2、那么考虑:
①对于一个点作为起点来讲,要么是左边是出口,要么右边是出口,到底哪边是模拟过程结果的出口呢?
②其实并不难考虑,问题关键点就在于只有两种台阶(U/D),那么如果当前台阶是U,他要找字符串右边第一个D.相反,如果是D,他要找字符串左边第一个U.
那么其实如果我们对应当前点作为起点的话,其右边D的个数,如果是大于等于左边元素个数的话,那么结果一定是从左边出去。相反就是右边出去咯。
③在纸上手写模拟几种情况之后,不难发现,对应一个位子pos的出口是左边,那么pos-1的出口一定也是左边,而且其有一个递推性质:
ans【i】=ans【i-1】+位子i右边第一个D的位子-位子i左边元素的个数)*2-1.
其实就是在找另外一个D,使得整个序列的操作翻转过去,从左边作为出口出去需要多花费出来的步数。
④那么如果出口是右边,反过去考虑,也就是有:
ans【i】=ans【i+1】+(n-位子i左边第一个U的位子+1-位子i右边元素的个数)*2-1
3、过程维护一下,注意数据比较大,需要使用LL...
Ac代码:
#include<stdio.h>
#include<string.h>
using namespace std;
#define ll __int64
ll ans[1000050];
char a[1000050];
int main()
{
ll n;
while(~scanf("%I64d",&n))
{
memset(ans,0,sizeof(ans));
scanf("%s",a+1);
ll pos=1;
for(ll i=1;i<=n;i++)
{
while(pos<=n&&a[pos]=='U')pos++;
if(pos>n)break;
ans[i]=ans[i-1]+(pos-(i-1))*2-1;
pos++;
}
pos=n;
for(ll i=n;i>=1;i--)
{
while(pos>=1&&a[pos]=='D')pos--;
if(pos<1)break;
ans[i]=ans[i+1]+(n-pos+1-(n-i))*2-1;
pos--;
}
for(ll i=1;i<=n;i++)
{
printf("%I64d ",ans[i]);
}
printf("\n");
}
}