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挂掉了睡觉去--------------------------------------------------------------------------------------

Poi 2014 解题报告( 1 - 4 ,6 ),布布扣,bubuko.com

时间: 2024-12-05 23:31:46

Poi 2014 解题报告( 1 - 4 ,6 )的相关文章

ZOJ Monthly, June 2014 解题报告

A.Another Recurrence Sequence B.Gears 题目大意:有n个齿轮,一开始各自为一组,之后进行m次操作,包括以下4种类型: 1.合并两组齿轮,合并的两个应该反向旋转 2.把某个齿轮从所在组删除,自为一组,但不影响同组其它齿轮的状态与关系 3.询问两个齿轮是同向.反向或无关系(即不在同一组) 4.询问某个齿轮所在组的齿轮总数 分析:典型的并查集操作,但是注意两点: 1.由于操作3要询问两个齿轮的相对状态,因此对并查集中每个元素应当保存它的状态信息.状态是相对的,只需要

【百度之星2014~初赛(第二轮)解题报告】Chess

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]Chess>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=667 前言 最近要毕业了,有半年没做

【百度之星2014~初赛(第二轮)解题报告】JZP Set

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]JZP Set>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=668 前言 最近要毕业了,有半年

【百度之星2014~资格赛解题报告】

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<标题>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=666 前言 最近要毕业了,有半年没做比赛了.这次参加百度之星娱乐一下.现在写一下解题报

【百度之星2014~复赛)解题报告】The Query on the Tree

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~复赛)解题报告]The Query on the Tree>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=673 前言

【百度之星2014~初赛解题报告】

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛解题报告]>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=671 前言 最近要毕业了,有半年没做比赛了.这次参加百度

2014 UESTC 暑前集训队内赛(1) 解题报告

A.Planting Trees 排序+模拟 常识问题,将耗时排一个序,时间长的先种,每次判断更新最后一天的时间. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define Mod 1000000007 #define INT 2147483647 #define pi acos(-1.0)

2014 UESTC暑前集训数据结构专题解题报告

A.Islands 这种联通块的问题一看就知道是并查集的思想. 做法:从高水位到低水位依序进行操作,这样每次都有新的块浮出水面,可以在前面的基础上进行合并集合的操作.给每个位置分配一个数字,方便合并集合.同时将这些数字也排一个序,降低枚举的复杂度.合并集合时向四周查询浮出水面但是没有合并到同一集合的点进行合并. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath&

【百度之星2014~复赛 解题报告~正解】The Query on the Tree

声明 笔者近期意外的发现 笔者的个人站点http://tiankonguse.com/ 的非常多文章被其他站点转载.可是转载时未声明文章来源或參考自 http://tiankonguse.com/ 站点,因此.笔者加入此条声明. 郑重声明:这篇记录<[百度之星2014~复赛 解题报告~正解]The Query on the Tree>转载自 http://tiankonguse.com/的这条记录:http://tiankonguse.com/record/record.php?id=674