• [机房测试]10.25


    [机房测试]10.25

    T2爆0啦,只有123啦

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


    考试的时间点记录

    14:32 T1结束 开T2

    14:35 验证T1

    14:53 T2无思路,开T3

    15:12 开T3暴力

    16:11 T3 50分

    16:46 T2 50分有锅

    16:54 T2 改完

    board

    点双联通分量嘛,由于题目特殊,打个特判+记录度数也可以过

    change

    神仙。。。。

    逻辑推理+分类讨论
    结论是:如果a=1,10,100,1000并且b != 2a,那么答案是2,否则是1.
    考虑为什么,⾸先分析1,2,5,10这⼏个⼩的,如果a = 1,b >= 5,那么⼀定需要⾄少2,否则只需要1(这个⾃⼰可
    以枚举⽅案证明)。
    然后考虑⼤的的情况,举个例⼦,如果a = 10,b = 50,那么买了1之后,需要找零49,这个9肯定是⽤1,2,5凑出来
    的(这⾥的意思是,能拼出49,⼀定能拼出9,然后剩下的部分即使有1,2,5,他们也⼀定能拼出10),减掉他们之
    后相当于⽤10,20,去凑40,就回到了上⾯的情况。其他情况类似证明。

    #include<bits/stdc++.h>
    using namespace std ;
    const int MAXN = 100005 ;
    const int val[14]={0,1,2,5,10,20,50,100,200,500,1000,2000,5000,10000}; 
    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 T , A , B ; 
    int main(){
    	freopen("change.in","r",stdin);
    	freopen("change.out","w",stdout);
    	T = read() ;
    	while( T-- ){
    		A = read() , B = read() ; 
    		int flag = 2 ;
    		if( B == 1 || B == 100 || B == 10 || B == 1000 )flag-- ;
    		if( A != B*2 )flag-- ;
    		if( flag )cout<<1<<endl ;
    		else cout<<2<<endl ;	
    	}
    	return 0 ;
    }
    

    fill

    话说。。。为什么50分比满分还要难写啊!!!!!!!!!

    10分 ,枚举+树上暴跳
    +40分 , 转化为序列贪心右端点排序。

    话说,ssw02都想到了贪心,为啥没想到贪lca呢?

    按照询问的lca从深到浅贪心即可。

    如果左右点在dfn上没有被覆盖,那么把lca的子树全部打标记。

    用个数据结构维护下区间加即可。

    50

    #include<bits/stdc++.h>
    using namespace std ;
    const int MAXN = 100005 ; 
    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 T , N , M , ans , fa[MAXN] , dep[MAXN] , d[MAXN] , rev[MAXN] , cnt ;
    int head[MAXN] , to[MAXN*2] , nex[MAXN*2] , tot = 1 ;
    bool vis[MAXN] ; 
    struct ap{
    	int  a, b  ;
    }t[MAXN];
    inline bool cmp( ap x , ap y ){
    	return ( x.b == y.b )?(x.a<y.a):(x.b<y.b) ;
    }
    void  add( int x , int y ){
    	to[ ++tot ] = y , nex[tot] = head[x] , head[x] = tot ; 
    }
    bool lis( int x , int y ){
    	if( vis[x] || vis[y] )return true ;
    	if( x==y && vis[x]==0 )return false ; 
    	while( x!=y ){
    		if( dep[x] < dep[y] )swap( x,y ) ;
    		 if( vis[ fa[x] ] )return true ;
    		 x=fa[x] ;
    	}
    	return false ;
    }
    int check(){
    	int flag = (1<<30) ; 
    	for( int i=1 ; i<=M ; ++i ){
    		if( !lis( t[i].a , t[i].b ) )return flag ;
    	}
    	flag=0 ;
    	for( int i=1 ; i<=N ; ++i )if( vis[i] )flag++ ;
    	return flag ;
    }
    void  find( int stp ){
    	if( stp > N )return ;
    	vis[stp] = true ; ans = min( check() , ans ) ; 
    	find( stp+1 ) ;
    	vis[stp] = false ; ans = min( check() , ans ) ; 
    	find( stp+1 ) ;
    }
    void  dfs( int u , int father ){
    	fa[u] = father ;
    	for( int i = head[u] ; i ; i = nex[i] ){
    		if( to[i] == father )continue ;
    		dep[ to[i] ] = dep[u] + 1 ;
    		dfs( to[i] , u ) ;  
    	}
    }
    void  dfs2( int u , int father ){
    	fa[u] = father ; rev[u] = ++cnt ; 
    	for( int i = head[u] ; i ; i = nex[i] ){
    		if( to[i] == father )continue ;
    		dfs2( to[i] , u ) ;
    	}
    }
    void  work1(){
    	int m1 , m2 ; ans = (1<<30) ; 
    	for( int i = 1 ;  i < N ; ++i ){
    		m1 = read() , m2 = read() ;
    		add( m1 , m2 ) , add( m2 , m1 ) ; 
    	} 
    	dfs( 1 , 1 ) ;
    	for( int i = 1 ; i <= M ; ++i )t[i].a = read() , t[i].b = read() ;
    	find( 1 ) ; 
    	cout<<min( ans , N )<<endl ;
    }
    void  work2(){
    	int m1 , m2 ; ans = (1<<30) ;
    	for( int i = 1 ; i < N ; ++i ){
    		m1 = read() , m2 = read() ; d[m1]++ , d[m2]++ ;
    		add( m1 , m2 ) , add( m2 , m1 ) ;
    	}
    	for( int i = 1 ; i <= N ; ++i )
    		if( d[i] == 1 ){dfs2( d[i] , d[i] ) ; break ; }//扫出新的序列 
    	for( int i = 1 ; i <= M ; ++i ){
    		m1 = read() , m2 = read() ;
    		if( rev[m1] > rev[m2] )swap( m1 , m2 ) ;
    		t[i].a=rev[m1] , t[i].b = rev[m2] ;
    	}
    	sort( t+1 , t+M+1 , cmp ) ; 
    	ans = 1 ; int now = t[1].b ;
    	for( register int i = 2 ; i <= M ; ++i ){
    		if( t[i].a <= now )continue ;
    		now = t[i].b , ans++ ;
    	}
    	cout<<min(ans,N)<<endl ;
    }
    void  clear(){
    	for( register int i = 1 ; i <= N ; ++i )
    	rev[i] = d[i] = t[i].a = t[i].b = head[i] = dep[i] = fa[i] = vis[i] = 0 ;
    	tot = 1 , ans = (1<<30) , cnt = 0 ;
    }
    int main(){
    	freopen("fill.in","r",stdin) ;
    	freopen("fill.out","w",stdout) ;
    	T = read() ;
    	while( T-- ){
    		N = read() , M = read() ;
    		if( M==0 ){puts("0");continue;} 
    		if( N <= 12 && M <= 30 )work1() ;
    		else work2() ; 
    		clear() ;
    	}
    	return 0 ;
    }
    

    ac

    #include<bits/stdc++.h>
    using namespace std ;
    #define ll long long
    const int MAXN = 100005 ; 
    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 T , N , M , tot = 1 , cnt ;
    int  head[MAXN] , to[MAXN*2] , nex[MAXN*2] , dep[MAXN] , dfn[MAXN] , rev[MAXN] , anc[MAXN][20] , out[MAXN] ;
    int  c[MAXN] ;
    struct ap{
    	int l , r , tp ; 
    }t[MAXN];
    //-------------
    void  updata( int x , int y ){
    	for( ; x <= N ; x += x&-x )c[x] += y ; 
    }
    ll sum( int x ){
    	ll anss = 0 ;
    	for( ; x ; x-= x&-x )anss += (ll)c[x] ;
    	return anss ; 
    }
    //-------------
    inline bool cmp( ap x , ap y ){
    	return ( dep[ rev[x.tp] ] == dep[ rev[y.tp] ] )?( x.tp > y.tp ):(dep[ rev[x.tp] ]>dep[ rev[y.tp] ]) ;
    	//return dep[ rev[x.tp] ]>dep[ rev[y.tp] ] ;
    }
    void add( int x , int y ){
    	to[ ++tot ] = y , nex[tot] = head[x] , head[x] = tot ;
    }
    int lca( int x , int y ){
    	if( dep[x] < dep[y] )swap( x , y ) ; 
    	int t = dep[x] - dep[y] ;
    	for( int p=0 ; t ; t >>=1 , ++p )
    	    if( t&1 )x = anc[x][p] ;
    	if( x==y )return x ;
    	for( int p=17 ; anc[x][0] != anc[y][0] ; p-- )
    	    if( anc[x][p] != anc[y][p] )x=anc[x][p] , y=anc[y][p] ;
    	return anc[x][0] ;  
    }
    void  dfs( int u , int fa ){
    	anc[u][0] = fa , dfn[u] = ++cnt , rev[cnt] = u ; 
    	for( int i = 1 ; i <= 17 ; ++i )anc[u][i] = anc[ anc[u][i-1] ][i-1] ;
    	for( int i = head[u] ; i ; i = nex[i] ){
    		if( to[i] == fa )continue ;
    		dep[ to[i] ] = dep[u] + 1 ;
    		dfs( to[i] , u ) ;
    	}
    	out[u] = cnt ;
    }
    void  work(){
    	int m1 , m2 ; 
        for( int i = 1 ; i < N ; ++i ){
        	m1 = read() , m2 = read() ; 
        	add( m1 , m2 ) , add( m2 , m1 ) ;
        }
    	dfs( 1 , 1 ) ; 
    	for( int i = 1 ; i <= M ; ++i ){
    		m1 = read() , m2 = read() ;
    		int tp = lca( m1 , m2 ) ;  
    		if( dfn[m1] > dfn[m2] )swap( m1 , m2 ) ; 
    		t[i].l = dfn[m1] , t[i].r = dfn[m2] , t[i].tp = dfn[tp] ; 
    	}	
    	sort( t+1 , t+M+1 , cmp ) ; int ans = 0 ;
    	for( int i = 1 ; i <= M ; ++i ){
    		//if( sum( t[i].tp )  )continue ;
    		if( sum( t[i].l ) || sum( t[i].r ) )continue ;
    		updata( t[i].tp , 1 ) , updata( out[ rev[ t[i].tp ] ]+1 , -1 ) ;ans++ ;
    	}
    	cout<<ans<<endl ;
    } 
    void  clear(){
    	for( register int i = 1 ; i <= max( N , M ) ; ++i )out[i] = t[i].tp = t[i].l = t[i].r = c[i] = head[i] = dep[i] = dfn[i] = rev[i] = 0 ;
    	tot = 1 , cnt = 0 ;
    }
    int main(){
    	freopen("fill.in","r",stdin) ;
    	freopen("fill.out","w",stdout) ;
    	T = read() ;
    	while( T-- ){
    		N = read() , M = read() ; 
    		work() ; 
    		clear() ; 
    	}
    	return 0 ;
    }
    
  • 相关阅读:
    JQ选择器
    设计模式
    招银网络面试
    斗鱼面经
    招银科技面经
    用户访问网站基本流程
    shell的条件判断
    crontab -e 和/etc/crontab的区别
    秘钥对登录配置
    CentOS6 x86_64最小化安装优化脚本
  • 原文地址:https://www.cnblogs.com/ssw02/p/11741064.html
Copyright © 2020-2023  润新知