[机房测试]11.11

[机房测试]11.11

突然觉得Liu_runda也不是那么毒瘤了。。。或许是ssw02的错觉
没人可以索要神秘礼物了

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


bit

ssw02傻逼了

读入

T组数据 , 每组3个限制

思路

50分做法:直接暴力即可

100分做法:考虑到inf的两种情况: ansxor , ansor 均为0 或者 ansor , ansand 均为0

然后就可以放心枚举每一位: 1 1 : 0 1 : 1 0 : 0 0 是否合法即可

#include<bits/stdc++.h>
using namespace std ;
#define ll long long
const ll mod = 1e15 ;
inline ll read(){
    ll 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 s*w ; 
}
ll T , ansand , ansxor , ansor ;
inline bool check( int x , int y ){
    if( ansand != -1 && ( (x&y) != ansand ) )return false ; 
    if( ansor != -1 && ( (x|y) != ansor ) )return false ; 
    if( ansxor != -1 &&( (x^y) != ansxor ) )return false ;
    return true ; 
}
inline bool check_bit( int x , int y , int i ){
    if( ansand != -1 && ( ( (ansand>>i ) &1 ) != (x&y) ) )return false ; 
    if( ansor != -1 && ( ( (ansor>>i)& 1 ) != (x|y) ) )return false ;
    if( ansxor != -1 && ( ( (ansxor>>i)&1 ) != (x^y) ) )return false ;
    return true ;
}
void  work1(){//1~5
    ll ans = 0 ; 
    for( register int i = 0 ; i <= ansor ; ++i )
        for( register int j = 0 ; j <= ansor ; ++j ){
            if( check( i , j ) )ans++ ; 
        }
    cout<<ans<<endl ; 
}
void  work2(){//6~10
    ll ans = 0 ;
    for( register int i = ansand ; i <= ansor ; ++i )
        for( register int j = ansand ; j <= ansor ; ++j ){
            if( check( i , j ) )ans++ ; 
        }
    cout<<ans<<endl ; 
}
void  work3(){//11~20
    ll ans = 1LL , tot = 0 , tott = 0 ;
    if( ansor == -1 && ansand == -1 ){cout<<"inf";return ;}
    if( ansor == -1 && ansxor == -1 ){cout<<"inf";return ;}
    ll xx = ansor ; if(xx!=-1)while(xx)tott++ , xx>>=1 ; tot = max( tott , tot ) , tott = 0 ; 
     xx = ansxor ; if(xx!=-1)while(xx)tott++ , xx>>=1 ; tot = max( tott , tot ) , tott = 0 ; 
     xx = ansand ; if(xx!=-1)while(xx)tott++ , xx>>=1 ; tot = max( tott , tot ) , tott = 0 ; 
    for( int i = tot-1 ; i >= 0 ; --i ){
        ll now = 0 ; 
        if( check_bit( 1 , 1 , i ) )now+=1 ; 
        if( check_bit( 0 , 1 , i ) )now+=2 ; 
        if( check_bit( 0 , 0 , i ) )now+=1 ;
        ans *= now ;
    }
    cout<<ans<<endl ; 
}
int main(){
    freopen("bit.in","r",stdin) ; 
    freopen("bit.out","w",stdout ) ; 
    T = read() ; 
    while( T-- ){
        ansand = read() , ansor = read() , ansxor = read() ; 
        if(ansor <= 1024 && ansor != -1 )work1() ;
        else if( ansor - ansand <= 5000 && ansor != -1 && ansand != -1 )work2() ;
        else work3() ;
    } 
    return 0 ; 
}

jihe

一来就想 bitset , 感觉过不了 , 先模拟一下吧 , ??? 怎么模拟模拟就 A 了呢?

把加减操作和序列分离即可,尽量将复杂度放在给出的 SUM 个数,而不要放在原序列上 ,维护较小的集合即可 。

按照时间染色,∩ 操作如何解决 ? 2 个数组滚来滚去即可。

同时考虑到这个问题:出题人是 Liu_runda ,空间开 2*( SUM + opt ) (正负操作)。

然后模拟模拟模拟。。。。

#include<bits/stdc++.h>
using namespace std ;
#define ll long long
const int MAXN = 2300005 , H = 1150000 ; 
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 s*w ; 
}
int T , opt , size , now=1 , vis1[MAXN] , vis2[MAXN] , cnt ;
bool c1[MAXN] , c2[MAXN]; 
ll sum , add ;
void  insert( int val ){
    if( now ){
        if( c1[val+H-add] && vis1[val+H-add] == cnt ){
            vis1[val+H-add] = cnt ; return ;
        }
        else{
            c1[val+H-add] = true ; vis1[val+H-add] = cnt ; 
            size++ ; sum += (ll)val ; 
        }
    }
    else{
        if( c2[val+H-add] && vis2[val+H-add] == cnt ){
            vis2[val+H-add] = cnt ; return ;
        }
        else{
            c2[val+H-add] = true ; vis2[val+H-add] = cnt ; 
            size++ ; sum += (ll)val ; 
        }
    }
}
void  New_insert( int val ){
    if( now ){
        if( !c2[val+H-add] || ( vis2[val+H-add] != cnt-1 ) )return ;
        else{
            c1[val+H-add] = true ; vis1[val+H-add] = cnt ; 
            size++ ; sum += (ll)val ; 
        }
    }
    else{
        if( !c1[val+H-add] || ( vis1[val+H-add] != cnt-1 ) )return ;
        else{
            c2[val+H-add] = true ; vis2[val+H-add] = cnt ;
            size++ ; sum += (ll)val ; 
        }
    }
}
int main(){
    freopen("jihe.in","r",stdin) ; 
    freopen("jihe.out","w",stdout) ;
    T = read(); int m1 ;  
    while( T-- ){
        opt = read() ; 
        if( opt == 1 ){
            int numb = read() ; 
            for( register int i = 1 ; i <= numb ; ++i ){
                m1 = read() ; insert( m1 ) ; 
            }
        }
        else if( opt == 2 ){
            now ^= 1 , sum = 0 , size = 0 , cnt++ ;
            int numb = read() ; 
            for( register int i = 1 ; i <= numb ; ++i ){
                m1 = read() ; New_insert( m1 ) ; 
            }
        }
        else if( opt == 3 )add++ , sum += (ll)size; 
        else add-- , sum -= (ll)size ; 
        printf("%lld\n",sum) ; 
    }   
    return 0 ; 
}

这个坑等ssw02,,,,,,,可能填不了了。

总结

ssw02蠢了。。

T1: inf的性质可以再推敲一下 , 这样就可以多拿50分 。

T2: T1正解没思路后马上开T2, 上个厕所就想出来了 。 不过按时间染色的细节是Debug的时候才想到的。(幸好Liu_runda给了那么多样例)

T3: 猜到是防AC题目,打了35暴力,结果还是被判重卡掉了15分 (要是解决判重这道题就没意义了)

猜你喜欢

转载自www.cnblogs.com/ssw02/p/11836978.html