1. 程式人生 > >Codeforces 909 C. Python Indentation (DP+樹狀數組優化)

Codeforces 909 C. Python Indentation (DP+樹狀數組優化)

mes 循環 leo int 鏈接 樹狀 include sin 語句

題目鏈接: Python Indentation

題意:

  Python是沒有大括號來標明語句塊的,而是用嚴格的縮進來體現。現在有一種簡化版的Python,只有兩種語句:

 (1)‘s‘語句:Simple statements. 相當於一般語句。(2)‘f‘語句:For statements. 相當於for循環,並且規定它的循環體不能為空。

 然後給你一段沒有縮進的Python程序,共n行(n <= 5000)。問你添加縮進後,有多少種合法且不同的Python程序。

題解:題目解析

  DP過去,如果第i個位置是‘f‘的話,dp[i][j]只加到dp[i+1][j+1]上,如果是‘s’則可以加到從dp[i][0,j]的所有數上。區間假發可以用樹狀數組優化,把復雜度降到(n×n×log(n))。這道題讓我發現long long操作要比int慢一倍左右,還有MOD操作是真滴慢,遇到MOD操作可以用if降低時間。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAX_N = 5e3+9;
 4 const int MOD = 1e9+7;
 5 char vec[MAX_N];
 6 int dp[MAX_N][MAX_N];
 7 void add(int pos,int x,int num)
 8 {
 9     if(num<0) num+=MOD;
10     for(;x<MAX_N;x+=(x&-x))
11     {
12         dp[pos][x]=dp[pos][x]+num;
13 if(dp[pos][x]>=MOD) dp[pos][x]-=MOD; 14 } 15 } 16 int sum(int pos,int x) 17 { 18 int ans = 0; 19 for(;x>0;x-=(x&-x)) 20 { 21 ans=ans+dp[pos][x]; 22 if(ans>=MOD) ans-=MOD; 23 } 24 return ans; 25 } 26 int main() 27 { 28 int N,M,T; 29 while
(cin>>N) 30 { 31 memset(dp,0,sizeof(dp)); 32 for(int i=1;i<=N;i++) 33 { 34 cin>>vec[i]; 35 } 36 dp[1][1] = 1; 37 for(int i=1;i<=N;i++) 38 { 39 for(int j=1;j<=i;j++) 40 { 41 int t = sum(i,j); 42 if(vec[i] == f) 43 { 44 add(i+1,j+1,t); 45 add(i+1,j+2,-t); 46 } 47 else 48 { 49 add(i+1,1,t); 50 add(i+1,j+1,-t); 51 } 52 } 53 } 54 int ans = 0; 55 for(int i=1;i<=N;i++) 56 { 57 ans = ans+sum(N,i); 58 if(ans>=MOD) ans-=MOD; 59 } 60 cout<<(ans+MOD)%MOD<<endl; 61 } 62 return 0; 63 }

Codeforces 909 C. Python Indentation (DP+樹狀數組優化)