zoukankan      html  css  js  c++  java
  • [机房测试]11.7

    [机房测试]11.7

    连续两天低级错误送分,本来考的分就不多,直接送下300了。
    %骆神600吊打std

    欢迎转载ssw02的博客:https://www.cnblogs.com/ssw02/p/11814079.html


    你相信引力吗

    不,我不相信

    读入

    一个数N表示环的长度 , 然后N个数表示

    思路

    30分做法,提供一个N^2的思路。

    考虑破环为链,把链复制接在后面,只靠虑一个点向后所能得到的贡献。这个可以N^2记录重边,很好写。

    满分做法:考虑到破环时,不如把最大的点作为起点断开环,这样可以保证没有跨过这个环的贡献值。这个东西开个栈就可以维护。

    同时考虑到有可能端点和序列的另一端(毕竟是环)的贡献,这种贡献只有不断倒叙得到最大值才可以得到,逆序循环一遍即可。

    #include<bits/stdc++.h>
    using namespace std ;
    #define ll long long
    const int MAXN = 5000005 ; 
    inline int read(){
    	int s=0 ; char g=getchar() ; while( g>'9'||g<'0')g=getchar() ; 
    	while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ; 
    }
    int N , a[MAXN*2] , b[MAXN] , st[MAXN] , num[MAXN] ;
    bool vis[705][705] , used[MAXN] ;  
    void  work1(){
    	int  tot1 = 0 ; 
    	for( int i = 1 ; i <= N ; ++i ){
    		int maxx = 0 ;
    		for( int j = i+1 ; j < i+N ; ++j ){
    			if( maxx <= a[j] && maxx <= a[i] ){
    				int k = j ; 
    				if( k > N ) k -= N ; if( vis[i][k] )continue ;
    				tot1++ ; vis[i][k] = vis[k][i] = true ;
    			}
    			maxx = max( maxx , a[j] ) ; 
    		} 
    	}
    	cout<<tot1 ; 
    }
    void  work2(){
    	int maxx = 0 , pos = 0 , top = 0 ; 
    	for( int i = 1 ; i <= N ; ++i )
    	    if( a[i] > maxx )maxx=a[i],pos=i ;
    	for( int i = 1 , j = pos ; i <= N ; ++i , ++j ){
    		if( j > N ) j-=N ; b[i]=a[j] ;//断环为链 
    	} 
    	ll ans = 0 ;
    	for( int i = 1 ; i <= N ; ++i ){
    		while( top && st[top]<b[i] )ans += (ll)num[top--] ;
    		if( st[top] == b[i] )ans += (ll)num[top],num[top]++ ;
    		else st[++top] = b[i] , num[top] = 1 ;
    		if( top > 1 )ans++ ; 
    	}
    	maxx = 0 , pos = 0 ;
    	for( int i = N ; i > 1 ; --i )
    	    if( b[i] > maxx )ans++ , maxx = b[i] , pos = 1 ; 
    	    else if( b[i] == maxx )ans++ , pos++ ;
    	cout<<ans-pos ;
    }
    int main(){
    	freopen("jolyne.in","r",stdin) ;
    	freopen("jolyne.out","w",stdout) ;
    	N = read() ; int flag = true ;
    	for( register int i = 1 ; i <= N ; ++i ){
    		a[i] = a[i+N]= read() ;
    		if( i != 1 )if( a[i] != a[i-1] )flag = false ;
    	} 
    	if( N <= 700 ){work1() ; return 0 ;}
    	if( flag ){cout<<(ll)N*(ll)(N-1)/2LL ;return 0;}
    	else work2() ; 
    }
    

    停不下来的团长奥尔加

    5分钟秒切题,为一的价值就是教会ssw02别忘了先+mod在取模。。。。

    只要想到要通过一个点必须走这个点偶数次,借用一下汉诺塔的思想,sum[i]表示第一次走到i花费的时间。走过他就需要触发一次刺客伍六七。。回到pi,相当于你有回到了第一次来到pi的状态,在走到i就可以通过i了。

    方程很简单 sum[i] = sum[i-1]*2-sum[p[i-1]]+2 , sum[1] = 0 , sum[N+1]为所求

    #include<bits/stdc++.h>
    using namespace std ;
    const int MAXN = 1000005 , mod = 1e9+7 ; 
    inline int read(){
    	int s=0 ; char g=getchar() ; while( g>'9'||g<'0')g=getchar() ; 
    	while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ; 
    }
    int sum[MAXN] , p[MAXN] , N ;//还没我快读长。。。。。
    int main(){
    	freopen("rideon.in","r",stdin) ; 
    	freopen("rideon.out","w",stdout) ;
    	N = read() ; 
    	for( register int i = 1 ; i <= N ; ++i )p[i] = read() ; sum[1] = 0 ; 
    	for( register int i = 2 ; i <= N+1 ; ++i ){
    		sum[i] = ( (2*sum[i-1]-sum[p[i-1]]+2)%mod+mod )%mod ;
    	}
    	cout<<sum[N+1] ;
    } 
    
    

    Lesson5!

    好题,ssw02也讲不太清楚,两种方法只做了一种,做完堆做法在放(ssw02好久没写过堆了)

    代码

    总结

    ssw02蠢了。。

    T1读题花了50分钟还没读懂(不是ssw02语文菜,而是出题人没有给样例解释。。。算了还是ssw02菜),做法一来就想复制两倍,这个惯性思维有问题。

    T2 : 5分钟切完,10分钟测完极限数据(为何ssw02搓的极限数据刚好没报负啊!!!)

    T3 : 暴力topo可以写55分,正解是BZOJ3828原题。

  • 相关阅读:
    POJ
    POJ
    HDU-3374 String Problem (最小最大表示法)
    HDU-2328 Corporate Identity (暴力)
    HDU-1238 Substrings (kmp)
    kmp处理题型总结
    Numpy用户指南
    Docker 容器连接
    Docker 镜像使用
    docker容器的使用
  • 原文地址:https://www.cnblogs.com/ssw02/p/11814079.html
Copyright © 2011-2022 走看看