2013年山东省赛F题 Mountain Subsequences
先说n^2做法,从第1个,(假设当前是第i个)到第i-1个位置上哪些比第i位的小,那也就意味着a[i]可以接在它后面,f1[i]表示从第一个开始,以a[i]为结尾的不同递增序列的个数,要加上1,算上本身。正反各跑一遍,答案加一下(f1[i]-1)*(f2[i]-1)
优化就是,比a[i]小的,只有a[i]-1个
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<set> 8 #include<map> 9 #include<stack> 10 #include<cstring> 11 #define inf 2147483647 12 #define ls rt<<1 13 #define rs rt<<1|1 14 #define lson ls,nl,mid,l,r 15 #define rson rs,mid+1,nr,l,r 16 #define N 100010 17 #define For(i,a,b) for(int i=a;i<=b;i++) 18 #define p(a) putchar(a) 19 #define g() getchar() 20 21 using namespace std; 22 int n,ans; 23 char c[100010]; 24 int a[100010],f1[100010],f2[100010],sum[100010]; 25 26 void in(int &x){ 27 int y=1; 28 char c=g();x=0; 29 while(c<'0'||c>'9'){ 30 if(c=='-')y=-1; 31 c=g(); 32 } 33 while(c<='9'&&c>='0'){ 34 x=(x<<1)+(x<<3)+c-'0';c=g(); 35 } 36 x*=y; 37 } 38 void o(int x){ 39 if(x<0){ 40 p('-'); 41 x=-x; 42 } 43 if(x>9)o(x/10); 44 p(x%10+'0'); 45 } 46 47 void clear(){ 48 memset(f1,0,sizeof(f1)); 49 memset(f2,0,sizeof(f2)); 50 memset(sum,0,sizeof(sum)); 51 ans=0; 52 } 53 54 int main(){ 55 while(cin>>n){ 56 clear(); 57 cin>>(c+1); 58 For(i,1,n) 59 a[i]=c[i]-'a'+1; 60 For(i,1,n){ 61 For(j,1,a[i]-1) 62 f1[i]+=sum[j]; 63 f1[i]++; 64 f1[i]%=2012; 65 sum[a[i]]+=f1[i]; 66 } 67 68 memset(sum,0,sizeof(sum)); 69 70 for(int i=n;i;i--){ 71 For(j,1,a[i]-1) 72 f2[i]+=sum[j]; 73 f2[i]++; 74 f2[i]%=2012; 75 sum[a[i]]+=f2[i]; 76 } 77 For(i,2,n-1){ 78 ans+=(f1[i]-1)*(f2[i]-1)%2012; 79 ans%=2012; 80 } 81 o(ans);p(' '); 82 } 83 return 0; 84 85 }