首页 > 代码库 > Poi 2014 解题报告( 1 - 4 ,6 )
Poi 2014 解题报告( 1 - 4 ,6 )
撸了一下Poi 2014 ,看了一下网上题解不多,所以决定写一下。有的题应该是数据不强水过去了,等北京回来在写一下复杂度比较靠谱的代码 o(╯□╰)o
第一题:
题意是给定一个长度不大于1000000,只包括p和j的串,求一个最长的子串,要求子串任何一个前缀和后缀都满足p的数量不少于j的数量。
首先把p当做1,把j当做0,算出前缀和 sum[] ,原来的问题就转化为求一个最长区间 [l,r] ,使得任意的i∈[l,r],都有 sum[i] - sum[l-1] >= 0 并且 sum[r] - sum[i-1] >= 0 。然后就是陈题了。我的做法是用单调栈预处理出对于每个l-1,在满足第一个不等式的情况下向右最长延伸多长r[l-1],然后用线段树求出l-1到r[l]之间最大的sum的下标k,如果sum[k] >= sum[l-1] 那么[l,k] 就是一个合法的区间。这样复杂度是O(n+nlogn) = O(nlogn),跑了1.4s,代码1500B左右。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <stack> 5 using namespace std ; 6 const int N = 1000000 + 10 ; 7 char s[N] ; 8 int p[N] ,a[N<<2] ,r[N] ,Q ,st[N] ,top ,M ; 9 void calM( int n ){ 10 for( n -- ,M = 1 ;M <<= 1 ,n >>= 1 ; ) ; 11 } 12 int query( int s ,int t ){ 13 if(s==t) return a[s+M]; 14 int ans = p[a[s+=M]] > p[a[t+=M]] ? a[s] : a[t] ; 15 for( ;s ^ t ^ 1 ;s >>= 1 ,t >>= 1 ){ 16 if(~s&1) ans = p[a[s^1]] > p[ans] ? a[s^1] : ans ; 17 if( t&1) ans = p[a[t^1]] > p[ans] ? a[t^1] : ans ; 18 } 19 return ans ; 20 } 21 void update( int x ,int t ){ 22 for( a[x+=M] = t ;x >>= 1 ; ) 23 a[x] = p[a[x+x]] > p[a[x+x+1]] ? a[x+x] : a[x+x+1] ; 24 } 25 int solve( int n ){ 26 top = 0 ; 27 int ans = 0 ; 28 for( int i = 0 ;i <= n ;i ++ ){ 29 if( i ) update( i - 1 ,i ) ; 30 while( top && p[st[top-1]] > p[i] ){ 31 r[st[--top]] = i ; 32 } 33 st[top++] = i ; 34 } 35 for( int i = n ;i < M ;i ++ ) update( i ,n ) ; 36 while( top ){ 37 r[st[--top]] = n+1 ; 38 } 39 for( int i = 0 ;i <= n ;i ++ ){ 40 if( s[i] == ‘j‘ ) continue ; 41 if( ans > n - i ) break ; 42 Q = query( max( i ,1 ) - 1 ,r[i] - 1 ) ; 43 if( p[Q] > p[i] ) ans = max( ans ,Q - i ) ; 44 } 45 printf( "%d\n" ,ans ) ; 46 } 47 int main(){ 48 int n ; 49 scanf( "%d %s" ,&n ,s ) ; 50 calM( n+1 ) ; 51 for( int i = 1 ;i <= n ;i ++ ) 52 p[i] = p[i-1] + ( s[i-1] == ‘p‘ ? 1 : -1 ) ; 53 solve(n) ; 54 }
-------------------------------------------------------------------------------------坑爹的BZOJ挂掉了睡觉去--------------------------------------------------------------------------------------
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。