【CodeForces】446C Number of Ways
阿新 • • 發佈:2019-02-04
題目分析:首先求出所有相加為2/3sum的位置,用字尾和求出從這個點開始到結尾內相加為2/3sum的點的個數suffix_sum[ i ]。最後再for一遍,每到一個1/3sum的點i,ans += suffx_sum[ i + 1]。
最後輸出ans即可。
程式碼如下:
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> using namespace std ; typedef long long LL ; #define REP( i , a , b ) for ( int i = a ; i < b ; ++ i ) #define REV( i , a , b ) for ( int i = a ; i >= b ; -- i ) #define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define CLR( a , x ) memset ( a , x , sizeof a ) #define CPY( a , x ) memcpy ( a , x , sizeof a ) const int MAXN = 500005 ; bool vis[MAXN] ; int suffix_sum[MAXN] ; int a[MAXN] ; int n ; void solve () { LL sum = 0 ; FOR ( i , 1 , n ) { scanf ( "%d" , &a[i] ) ; sum += a[i] ; } if ( sum % 3 ) printf ( "0\n" ) ; else { CLR ( vis , 0 ) ; CLR ( suffix_sum , 0 ) ; LL tmp = 0 , ans = 0 ; FOR ( i , 1 , n ) { tmp += a[i] ; if ( tmp * 3 == sum * 2 ) vis[i] = 1 ; } REV ( i , n - 1 , 1 ) suffix_sum[i] = suffix_sum[i + 1] + vis[i] ; tmp = 0 ; FOR ( i , 1 , n - 1 ) { tmp += a[i] ; if ( tmp * 3 == sum ) ans += suffix_sum[i + 1] ; } printf ( "%I64d\n" , ans ) ; } } int main () { while ( ~scanf ( "%d" , &n ) ) solve () ; return 0 ; }