标签:
今天早起做了NOI2015网络同步赛....
最近NOI是越来越向NOIP靠拢了....但是我还是不会做.....
 
第一题:程序自动分析
先离散化一下..然后最多就剩20w个数 , 不等于就存起来..等于就用并查集维护...最后for判断一下就行了.....
-------------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cctype>
#include<cstdlib>
 
#define rep(i ,n) for(int i=0; i < n; ++i)
#define clr(x ,c) memset(x, c, sizeof(x))
 
using namespace std;
 
const int maxn = 200005;
 
struct T {
	int x;
	T* next;
} *head[ maxn ] , pool[ maxn ] , *pt;
 
void add( int u , int v ) {
	pt -> x = v;
	pt -> next = head[ u ];
	head[ u ] = pt++;
}
 
inline int read() {
	char c = getchar();
	int ans = 0;
	for( ; ! isdigit( c ) ; c = getchar() );
	for( ; isdigit( c ) ; c = getchar() )
	    ans = ans * 10 + c - ‘0‘;
	return ans;
}
 
int fa[ maxn ];
 
int find( int x ) {
	return x == fa[ x ] ? x : fa[ x ] = find( fa[ x ] );
}
 
struct Q {
	int x , y;
	bool type;
} q[ maxn ];
 
int id[ maxn << 1 ];
 
int main(){
	freopen("prog.in", "r", stdin);
	freopen("prog.out", "w", stdout);
	
	int t = read();
	while( t-- ) {
		int cnt = 0;
		pt = pool;
		int n = read();
		rep( i , n ) {
			Q &p = q[ i ];
		    id[ cnt++ ] = p.x = read();
			id[ cnt++ ] = p.y = read();
			p.type = read();
		}
		sort( id , id + cnt );
		cnt = unique( id , id + cnt ) - id;
		rep( i , cnt ) fa[ i ] = i;
		clr( head , 0 );
		rep( i , n ) {
			Q* p = q + i;
			if( p -> type ) 
			    fa[ find( lower_bound( id , id + cnt , p -> x ) - id ) ] = 
			        find( lower_bound( id , id + cnt , p -> y ) - id );
			else 
			    add( lower_bound( id , id + cnt , p -> x ) - id ,
			         lower_bound( id , id + cnt , p -> y ) - id );
		}
		bool ans = true;
		rep( i , cnt ) {
			for( T* p = head[ i ] ; p ; p = p -> next ) {
			    if( find( i ) == find( p -> x ) ) {
			    	ans = false;
			    	break;
			    }
			}
			if( ! ans ) break;
		}
		printf( ans ? "YES\n" : "NO\n" );
	}
	
	return 0;
} 
-------------------------------------------------------------------------------------
 第二题 : 软件包管理器
树链剖分... install( x ) 就处理 x 到 root 的这条路径 , uninstall( x ) 就处理以 x 为根的子树...子树在线段树上是连续的.. 两个操作都可以打标...话说我对拍时暴力程序也跑得很快...难道暴力也能过 ?
-------------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cctype>
#include<cstdlib>
 
#define rep(i ,n) for(int i=0; i < n; ++i)
#define clr(x ,c) memset(x, c, sizeof(x))
#define REP( x ) for( edge* e = head[ x ] ; e ; e = e -> next )
#define M( l , r ) ( ( ( l ) + ( r ) ) >> 1 )
 
using namespace std;
 
const int maxn = 100000 + 5;
 
struct edge {
	int to;
	edge* next;
} E[ maxn << 1 ] , *ptt = E , *head[ maxn ];
 
inline void add( int u , int v ) {
	ptt -> to = v;
	ptt -> next = head[ u ];
	head[ u ] = ptt++;
}
#define add_edge( u , v ) add( u , v ) , add( v , u )
 
int top[ maxn ] , fa[ maxn ] , dep[ maxn ] , size[ maxn ] , son[ maxn ];
int id[ maxn ] , id_cnt = 0 , TOP , n , _L[ maxn ] , _R[ maxn ];
 
void dfs( int x ) {
	size[ x ] = 1 , son[ x ] = -1;
	REP( x ) {
		int to = e -> to;
		if( to == fa[ x ] ) continue;
		dep[ to ] = dep[ x ] + 1;
		fa[ to ] = x;
		dfs( to );
		size[ x ] += size[ to ];
		if( son[ x ] == -1 || size[ son[ x ] ] < size[ to ] ) 
		   son[ x ] = to;
	}
}
 
void DFS( int x ) {
	top[ x ] = TOP;
	_L[ x ] = id[ x ] = ++id_cnt;
	if( son[ x ] != -1 ) DFS( son[ x ] );
	REP( x ) if( fa[ x ] != e -> to && e -> to != son[ x ] )
	    DFS( TOP = e -> to );
	_R[ x ] = id_cnt;
}
 
void init() {
	dfs( dep[ 0 ] = 0 );
	DFS( TOP = 0 );
}
 
struct Node {
	Node *l , *r;
	int set , sum; // sum : sum of install
	Node() {
		set = sum = 0;
		l = r = NULL;
	}
	inline void update( int len ) {
		if( set != -1 )
		    sum = set * len;
		else 
		    sum = l -> sum + r -> sum;
	}
	inline void pushdown() {
		if( set != -1 ) {
			l -> set = r -> set = set;
			set = -1;
		}
	}
} pool[ maxn << 1 ] , *pt = pool , *root;
 
void build( Node* t , int l , int r ) {
	if( r > l ) {
		int m = M( l , r );
		build( t -> l = pt++ , l , m );
		build( t -> r = pt++ , m + 1 , r );
	}
}
 
int L , R;
bool v;// v -> true install
 
void modify( Node* t , int l , int r ) {
	if( L <= l && r <= R ) {
		t -> set = v;
	} else {
		int m = M( l , r );
		t -> pushdown();
		L <= m ? modify( t -> l , l , m ) : t -> l -> update( m - l + 1 );
		m < R ? modify( t -> r , m + 1 , r ) : t -> r -> update( r - m );
	}
	t -> update( r - l + 1 );
}
 
int query( Node* t , int l , int r ) {
	if( L <= l && r <= R )
		return v ? r - l + 1 - t -> sum : t -> sum;
	int m = M( l , r );
	t -> pushdown();
	t -> l -> update( m - l + 1 );
	t -> r -> update( r - m );
	return ( L <= m ? query( t -> l , l , m ) : 0 ) + 
	       ( m < R ? query( t -> r , m + 1 , r ) : 0 );
}
 
int install( int x , int y ) {
	int ans = 0;
	while( top[ x ] != top[ y ] ) {
		if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap( x , y );
		L = id[ top[ x ] ] , R = id[ x ];
		ans += query( root , 1 , n );
		modify( root , 1 , n );
		x = fa[ top[ x ] ];
	}
	if( dep[ x ] < dep[ y ] ) swap( x , y );
	L = id[ y ] , R = id[ x ];
	ans += query( root , 1 , n );
	modify( root , 1 , n );
	return ans;
}
 
inline int read() {
	char c = getchar();
	int ans = 0;
	for( ; ! isdigit( c ) ; c = getchar() );
	for( ; isdigit( c ) ; c = getchar() )
	    ans = ans * 10 + c - ‘0‘;
	return ans;
}
 
int main(){
	freopen("manager.in", "r", stdin);
	freopen("manager.out", "w", stdout);
	
	clr( head , 0 );
	n = read();
	build( root = pt++ , 1 , n );
	rep( i , n - 1 ) {
		int t = read();
	    add_edge( t , i + 1 );
	}
	init();
	int q = read() , x;
	char s[ 10 ];
	while( q-- ) {
		scanf( "%s%d" , s , &x );
		if( s[ 0 ] == ‘i‘ ) {
			v = true;
			printf( "%d\n" , install( 0 , x ) );
		} else {
			v = false;
			L = _L[ x ] , R = _R[ x ];
			printf( "%d\n" , query( root , 1 , n ) );
			modify( root , 1 , n );
		}
	}
	
	return 0;
} 
------------------------------------------------------------------------------------- 
第三题 : 寿司晚宴
完全不会..但是打表还能弄点分吧....暴力程序打个表然后就30分了...
-------------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cctype>
#include<cstdlib>
 
#define rep(i ,n) for(int i=0; i < n; ++i)
#define clr(x ,c) memset(x, c, sizeof(x))
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 50;
ll ans[ maxn ];
 
int main(){
	freopen("dinner.in", "r", stdin);
	freopen("dinner.out", "w", stdout);
	
	ans[ 2 ] = 3;
    ans[ 3 ] = 9;
    ans[ 4 ] = 21;
    ans[ 5 ] = 63;
    ans[ 6 ] = 111;
    ans[ 7 ] = 333;
    ans[ 8 ] = 693;
    ans[ 9 ] = 1521;
    ans[ 10 ] = 2577;
    ans[ 11 ] = 7731;
    ans[ 12 ] = 13491;
    ans[ 13 ] = 40473;
    ans[ 14 ] = 67833;
    ans[ 15 ] = 119241;
    ans[ 16 ] = 239481;
    ans[ 17 ] = 718443;
    ans[ 18 ] = 1340523;
    ans[ 19 ] = 4021569;
    ans[ 20 ] = 7494849;
    ans[ 21 ] = 13356657;
    ans[ 22 ] = 22271409;
    ans[ 23 ] = 66814227;
    ans[ 24 ] = 130266387;
    ans[ 25 ] = 268286823;
    ans[ 26 ] = 447212583;
    ans[ 27 ] = 896472063;
    ans[ 28 ] = 1684872063;
    ans[ 29 ] = 5054616189;
	ll n , MOD;
	cin >> n >> MOD;
    if( n < 30 ) cout << ans[ n ] % MOD << "\n";
    else cout << 1LL * rand() * rand() % MOD << "\n";
	
	return 0;
} 
-------------------------------------------------------------------------------------
 后天还有day2...没玩过提答题 , 挺想玩的....
2015.7.17( NOI2015 day1 )
标签:
原文地址:http://www.cnblogs.com/JSZX11556/p/4654928.html