题意给n让n个字母,求该串中存在多少个 a1 < ...< ai < ai+1 < Amax > aj > aj+1 > ... > an的情况
思路,枚举最大值,然后dp以s[i]为最大值,从前往后的逐渐增大的序列的个数,
这里用到了字母表的优化,由该题得出,此题不可以是n*n的时间复杂度,
所以要想到优化,如何优化呢,此时用的了字母本身,将每个字母在当前对应的个数进行保存,
然后枚举s[i]的字典序之前的加起来就行了
善于用题目中的条件,数学模型的建立
#include<bits/stdc++.h>
#define LL long long
using namespace std;
#define eps 1E-10
#define INF 0x3f3f3f3f
int di[100010],dj[100010];
int vi[100],mi[100];
char s[1000010];
int main()
{
int n;
while(~scanf("%d",&n))
{
scanf("%s",s);
memset(di,0,sizeof(di));
memset(vi,0,sizeof(vi));
memset(dj,0,sizeof(dj));
for(int i=0;i<n;i++)
{
int biao=s[i]-'a';
for(int j=0;j<biao;j++)
{
di[i]=(di[i]+vi[j])%2012;
}
vi[biao]=(vi[biao]+di[i]+1)%2012;///本身单个字母自己就站一个位置所以加1。
}
memset(vi,0,sizeof(vi));
for(int i=n-1;i>=0;i--)
{
int biao=s[i]-'a'; ///二维枚举字母,加上字典序之前的数量就可以了
for(int j=0;j<biao;j++)
{
dj[i]=(dj[i]+vi[j])%2012;
}
vi[biao]=(vi[biao]+dj[i]+1)%2012;///本身单个字母自己就站一个位置所以加1。
}
LL sum=0;
for(int i=0;i<n;i++)
{
///cout<<di[i]<<" "<<dj[i]<<endl;
sum=(sum+di[i]*dj[i])%2012;
}
printf("%lld\n",sum);
}
return 0;
}