zoukankan      html  css  js  c++  java
  • 题解——[NOIP模拟]不正常全家桶

    题解——不正常团伙+国家+序列

    体面背景好评
    *关于ssw02,他炸了 *


    不正常团伙

    主要思路

    50分做法

    开桶暴力,统计即可。

    60分做法

    主席树加暴力

    100分做法

    由50分做法可得,莫队离线一下就可以了。(这里顺便借ZYC学长的代码优化了一下ssw02自己的莫队板子)

    由60分做法可得,主席树记录上一个位置即可。

    线段树做法,也是记录上一个位置。(区间染色也就这几种方法了)

    #include<bits/stdc++.h>
    using namespace std ;
    #define ll long long
    const int MAXN = 100005 ;
    inline int read(){
       int s=0 , w=1 ; char g=getchar() ;while(g>'9'||g<'0'){if(g=='-')w=-1;g=getchar();}
       while(g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ;return w*s ;
    }
    struct Seg{
       int l , r , id ;
    }t[ MAXN ];
    int N , M , block , a[ MAXN ] , pos[ MAXN ] , num[ MAXN ]  ;
    ll tot = 0 , ans[ MAXN ] ;
    inline bool cmp( Seg x , Seg y ){
       return ( pos[ x.l ]==pos[ y.l ] )?( x.r < y.r ) : ( pos[x.l] < pos[y.l] ) ;
    }
    inline void updata( int x , int  opt ){
       if( !opt ){//收缩 扩张 
       	--num[ a[ x ] ] ;
       	if( num[ a[ x ] ] > 2 ) tot -= a[ x ];
       	else if(num[ a[ x ] ] == 2) tot -= a[ x ]*3 ;  
       	else if(num[ a[ x ] ] == 1) tot += a[ x ] ;
       	else tot -= a[ x ] ; 
       	return;
       }
       ++num[ a[ x ] ] ;
       if( num[ a[ x ] ] > 3 )  tot += a[ x ];
       else if( num[ a[ x ] ] == 3 ) tot += a[ x ]*3 ;
       else if( num[ a[ x ] ] == 2 ) tot -= a[ x ] ;
       else tot += a[ x ];
    }
    void  Mo(){
       for( int l = 1 , r = 0 , i = 1 ; i <= M  ; ++i ){
       	while( l < t[ i ].l )updata( l++ , 0 ) ;
       	while( l > t[ i ].l )updata( --l , 1 ) ;
       	while( r < t[ i ].r )updata( ++r , 1 ) ;
       	while( r > t[ i ].r )updata( r-- , 0 ) ;
       	ans[ t[ i ].id ] = tot ;
       }
    }
    int main(){
       freopen("abnormal.in","r",stdin);
       freopen("abnormal.out","w",stdout);
       N = read() , M = read() , block = sqrt(N) ;
       for( int i = 1 ; i <= N ; ++i )a[ i ] = read() ;
       block = sqrt( N ) ;
       for( int i = 1 ; i <= N ; ++i )pos[ i ] = (i-1) / block+1 ;
       for( int i = 1 ; i <= M ; ++i )
       	t[ i ].l = read() , t[ i ].r = read() , t[ i ].id = i ;
       sort( t+1 , t+M+1 , cmp ) ;
       Mo() ;
       for( int i = 1 ; i <= M ; ++i )printf("%lld
    ",ans[ i ] ) ;
       return 0 ;
    } 
    

    作为一个OIer,要时刻保持对出题人的尊敬,尤其是本校金牌学长出的题。

    不正常国家

    重链剖分+trie树+启发式合并( SXK , std )
    trie树+无删除启发式合并( ZYC )
    树剖+trie树+启发式合并(其实和第一种差不多)

    不正常序列

    毒瘤出题人完美卡了所有平衡树。(最后有hzy卡时莽了过去)

    求中位数,用双堆吧。常数小了不止一个级别。

    #include<bits/stdc++.h>
    using namespace std ;
    #define ll long long
    const int MAXN = 1000005 , mod = 1e9+7 ;
    inline ll read(){
    	ll 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 ;
    }
    ll ans = 0 ;
    ll a[ MAXN ] , N , A , B , C ; 
    priority_queue<ll>ma,mi ;
    int  deal( int N ){
    	if( N%2 )return N/2+1 ;
    	else return N/2 ;
    }
    void  insert( int x ){
    	int u = mi.top() ;
    	if( x < u )mi.push( x ) ;
    	else ma.push( -x ) ;
    	while( mi.size() < ma.size() ){
    		int u = -ma.top() ; ma.pop() ;
    		mi.push( u ) ;
    	}
    	while( mi.size()-1 > ma.size() ){
    		int u = mi.top() ; mi.pop() ;
    		ma.push( -u ) ;
    	}
    }
    int main(){
    	freopen("unnormal.in","r",stdin) ;
    	freopen("unnormal.out","w",stdout) ;
    	A = read() , B = read() , C = read() , N = read() ;
    	mi.push(1) ;
    	ans = 1LL ;
    	for( ll i = 2 ; i <= N ; ++i ){
    		ll op = mi.top() ;
    		op = ( op*A%mod + B*i%mod + C )%mod ; 
    		insert(op);ans += (ll)op ;
    	}
    	cout<<ans<<endl ;
    }
    

    如有不足,请大佬指出

  • 相关阅读:
    Spine学习四
    Spine学习三
    用 C 语言开发一门编程语言 — 基于 Lambda 表达式的函数设计
    用 C 语言开发一门编程语言 — 变量元素设计
    用 C 语言开发一门编程语言 — Q-表达式
    C 编程异常 — double free or corruption (fasttop)
    用 C 语言开发一门编程语言 — S-表达式
    用 C 语言开发一门编程语言 — 异常处理
    用 C 语言开发一门编程语言 — 抽象语法树
    用 C 语言开发一门编程语言 — 语法解析器
  • 原文地址:https://www.cnblogs.com/ssw02/p/11593657.html
Copyright © 2011-2022 走看看