[机房测试]10.23

[机房测试]10.23

sss02 140大众低分送命了

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


attack

一个多次询问必经点的问题。

可以用灭绝树搞他。支配树板子

因为是DAG , 所以我们在跑DAG的是后将已经遍历过的点的父亲节点赋值为lca(前父亲,当前节点),倍增求lca的dep即可。

#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 N , M , Q , dep[ MAXN ] , anc[MAXN][20] ;
int to[MAXN] , nex[MAXN] , head[MAXN] , tot = 1 ; 
bool vis[MAXN] ; 
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 ; 
	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 ) ; 
	}
}
void  dfs2( int u , int fa ){
	if( !anc[u][0] ){
		anc[u][0] = fa ; 
	    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 ;
		if( vis[to[i]] ){
			int fat = lca( anc[ to[i] ][0] , u ) ;
			anc[ to[i] ][0] = fat ; dep[ to[i] ] = dep[fat] + 1 ;
			for( int j = 1 ; j <= 17 ; ++j )anc[ to[i] ][j] = anc[ anc[to[i]][j-1] ][j-1] ; 
		}  
		vis[to[i]] = true ;
		dfs2( to[i] , u ) ; 
	}
}
void  work1(){
	int m1 , m2 , now ;
	for( int i = 1 ; i <= M ; ++i ){
		m1 = read() , m2 = read() ; 
		add( m1 , m2 ) ; 
	}
	dfs( 1 , 1 ) ; 
	while( Q-- ){
		m1 = read() ; 
		if( m1 == 0 )printf("0\n") ;
		else if( m1 == 1 ){
			m2 = read() ;
			printf("%d\n",dep[m2]+1 ) ;
		}
		else{
			now = read() , m2 = read() ; now = lca( now , m2 ) ; 
			for( int i = 3 ; i <= m1 ; ++i ){
				m2 = read() ; now = lca( now , m2 ) ;
			}
			printf("%d\n",dep[now]+1) ;
		}
	}
}
void  work2(){
	vis[1] = true; 
	int m1 , m2 , now ;
	for( int i = 1 ; i <= M ; ++i ){
		m1 = read() , m2 = read() ; 
		add( m1 , m2 ) ; 
	}
	dfs2( 1 , 1 ) ;  
	while( Q-- ){
		m1 = read() ; 
		if( m1 == 0 )printf("0\n") ;
		else if( m1 == 1 ){
			m2 = read() ;
			printf("%d\n",dep[m2]+1 ) ;
		}
		else{
			now = read() , m2 = read() ; now = lca( now , m2 ) ; 
			for( int i = 3 ; i <= m1 ; ++i ){
				m2 = read() ; now = lca( now , m2 ) ;
			}
			printf("%d\n", dep[now]+1 ) ;
		}
	}
}
int main(){
	freopen("attack.in","r",stdin) ;
	freopen("attack.out","w",stdout ) ;
	N = read() , M = read() , Q = read() ; 
	if( M == N-1 )work1() ; 
	else work2() ; 
}

reverse

大水题,N^2 T 都可以过的就不用打hash了嘛。。。
题目的字典序最大是骗人的,合法最长情况只有一种

#include<bits/stdc++.h>
using namespace std ; 
int T , lena , lenb , lenans=0 ;
char a[1005],b[1005],c[1005],ans[1005];
bool  check( char x[] , char  y[] ){
	int  len = strlen(x) , lenn = strlen(y) ; 
	if( len != lenn )return false  ; 
	for( int i = 0 ; i < len ; ++i )
		if( x[i] != y[i] )return false ;
	return true ; 
} 
void  updata( char x[] ){
	int len = strlen( x ) , minn = min( len , lenans ) , flag = 0 ;
	if( len < lenans )return ;
	if( len > lenans ){
		memset( ans , 0 , sizeof(ans) ) ; lenans = len ;
		for( int i = 0 ; i < len ; ++i )ans[i] = x[i] ;return ;
	}
	for( int i = 0 ; i < len ; ++i )
		if( x[i] > ans[i] ){flag=1;break;}
		else if( x[i] < ans[i] ){flag=-1;break;}
	if( flag == 0 && len > lenans )flag = 1 ;
	if( flag == 1 ){
		memset( ans , 0 , sizeof(ans) ) ;
		for( int i = 0 ; i < len ; ++i )ans[i] = x[i] ;
	}
}
void  rev(){
	memset( c , 0 , sizeof(c) ) ;
	//cout<<a<<"   YYYYY   "<<endl ;
	for( int i = 0 ; i < lena ; ++i )c[lena-i-1] = a[i] ; 
	for( int i = 0 ; i < lena ; ++i )a[i] = c[i] ; 
	//cout<<a<<"   XXXXX   "<<endl<<endl ;
}
void  work(){
	if( check(a,b) ){cout<<a<<endl ; return ; }
	while( lena != 0 && lenb !=0 ){
		while( lena != lenb ){
			if( lena < lenb ){swap(lena,lenb);swap(a,b);}
			lena-- ; 
			if( a[lena]=='A' )a[lena]=0 ;
			else {
				a[lena] = 0 ; rev() ; 
			} 
		}
	    if( lena == lenb ){
		    if( check( a , b ) )updata( a ) ; 
		    lena-- ; 
		    if( a[lena]=='A' )a[lena]=0 ;
			else {
				a[lena] = 0 ; rev() ; 
			}
	    }
	}
	if( lenans == 0 )printf("-1\n");
	else cout<<ans<<endl ;
}
int main(){
	freopen("reverse.in","r",stdin);
	freopen("reverse.out","w",stdout) ;
	scanf("%d",&T);
	while( T-- ){
		memset( ans , 0 , sizeof(ans) ) ;
		lenans=0 ;
		scanf("%s",a) ; scanf("%s",b) ;
		lena = strlen(a) , lenb = strlen(b) ;
		work() ; 
		
	}
}

tree

分情况的期望DP

YYR讲过加强版,以后总结是一起放链接。

ssw02滚去颓废和复习概率期望了。

posted @ 2019-10-23 20:38  蓝银杏-SSW  阅读(167)  评论(0编辑  收藏  举报
//结束