不知道有没有大佬跟我一样写指针啊, 1~10RE,11~12AC
查看原帖
不知道有没有大佬跟我一样写指针啊, 1~10RE,11~12AC
105682
SASUKE__楼主2020/9/21 21:39

我没有数据也没法调啊

#include<bits/stdc++.h>

using namespace std;

#define setAllMax(x) memset(x,0x3f/5,sizeof x)
#define setAllMin(x) memset(x,0xf0,sizeof x)
#define checkMin(x,y) ((x)=(x)<(y)?(x):(y))
#define checkMax(x,y) ((x)=(x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))

inline long long r( ) {
	long long x = 0;
	short op = 1;
	char ch = getchar( );
	while( ch != '-' && !( '0' <= ch && ch <= '9' ) ) ch = getchar( );
	if( ch == '-' ) op = - 1, ch = getchar( );
	while( '0' <= ch && ch <= '9' ) {
		x = x * 10 + ch - '0';
		ch = getchar( );
	}
	return x*op;
}

#define inc(i,x,y) for(register int i=x;i<=y;++i)
#define dec(i,x,y) for(register int i=x;i>=y;--i)

#define int long long

class MULTI_SET {
	
	private:
		
		#define PNODE NODE*
		struct NODE {
			PNODE leftNode;
			PNODE rightNode;
			int amount;
			NODE( ) {
				amount = 0;
				leftNode = rightNode = NULL;
			}
		} ;
		PNODE root;
		int n;
		
		void pushup( PNODE &now ) {
			now -> amount = ( now -> leftNode != NULL? now -> leftNode -> amount : 0 ) 
							+ ( now -> rightNode != NULL? now -> rightNode -> amount : 0 );
		}
		void merge( PNODE &x, PNODE &y, int l, int r ) {
			if( y == NULL )
				return;
			if( x == NULL ) {
				x = y;
				y = NULL;
				return;
			}
			if( y -> leftNode == NULL && y -> rightNode == NULL ) {
				x -> amount += y -> amount;
				delete y;
				y = NULL;
				return;
			}
			int mid = ( l + r ) >> 1;
			merge( x -> leftNode, y -> leftNode, l, mid );
			merge( x -> rightNode, y -> rightNode, mid + 1, r );
			pushup( x );
			delete y;
			y = NULL;
		}
		
		void merge( PNODE &x, PNODE &y, int l, int r, const int &L, const int &R ) {
			if( y == NULL ) return;
			if( l > R || r < L ) 
				return;	
			if( L <= l && r <= R ) {
				merge( x, y, l, r );
				return;
			}
			if( x == NULL ) 
				x = new NODE;
			int mid = ( l + r ) >> 1;
			merge( x -> leftNode, y -> leftNode, l, mid, L, R );
			merge( x -> rightNode, y -> rightNode, mid + 1, r, L, R );
			pushup( x );
		}
		
		void mergeNumber( PNODE &now, int l, int r, const int &amount, const int &value ) {
			if( value < l || value > r ) return;
			if( now == NULL ) now = new NODE;
			if( l == r ) {
				now -> amount += amount;
				return;
			}
			int mid = ( l + r ) >> 1;
			mergeNumber( now -> leftNode, l, mid, amount, value );
			mergeNumber( now -> rightNode, mid + 1, r, amount, value );
			pushup( now );
		}
		
		int amountInSection( PNODE &now, int l, int r, const int &L, const int &R ) {
			if( now == NULL ) return 0;
			if( l > R || r < L ) return 0;
			if( L <= l && r <= R ) return now -> amount;
			int mid = ( l + r ) >> 1;
			return amountInSection( now -> leftNode, l, mid, L, R ) 
					+ amountInSection( now -> rightNode, mid + 1, r, L, R );
		}
		
		int findByOrder( PNODE &now, int l, int r, int order ) {
			if( order > now -> amount ) return - 1;
			if( order <= 0 ) return - 1;
			if( l == r ) return l;
			int mid = ( l + r ) >> 1;
			return max( findByOrder( now -> leftNode, l, mid, order ),
							findByOrder( now -> rightNode, mid + 1, r, order - now -> leftNode -> amount ) );
		}
		
		void print( PNODE now, const int l, const int r ) {
			if( now == NULL ) return;
			printf( "%lld %lld %lld\n", l, r, now -> amount );
			print( now -> leftNode, l, ( l + r ) >> 1 );
			print( now -> rightNode, ( ( l + r ) >> 1 ) + 1, r );
		}
		
	public:
		
		void free( PNODE &now ) {
			if( !now -> leftNode ) free( now -> leftNode );
			if( !now -> rightNode ) free( now -> rightNode );
			delete now;
			now = NULL;
		}
		
		void setSize( int N ) {
			n = N;
		}
		
		void merge( MULTI_SET another ) {
			merge( root, another.root, 1, n );
		}
		
		void merge( MULTI_SET another, const int L, const int R ) {
			merge( root, another.root, 1, n, L, R );
		}
		
		void mergeNumber( const int amount, const int value ) {
			mergeNumber( root, 1, n, amount, value );
		}
		
		int amountInSection( const int L, const int R ) {
			return amountInSection( root, 1, n, L, R );
		}
		
		int findByOrder( int order ) {
			if( order > root -> amount ) return - 1;
			return findByOrder( root, 1, n, order );
		}
		
		void print( ) {
			print( root, 1, n );
		}
		
} ;

MULTI_SET S[ 200005 ];

signed main( ) {
	int n, m, k = 1;
	n = r( );
	m = r( );
	inc( i, 1, n )
		S[ i ].setSize( n );
	inc( i, 1, n ) {
		int x = r( );
		S[ k ].mergeNumber( x, i );
	}
	inc( i, 1, m ) {
		int opt, a, b, c;
		opt = r( );
		a = r( );
		b = r( );
		switch( opt ) {
			case 0:
				c = r( );
				S[ ++ k ].merge( S[ a ], b, c );
				break;
			case 1:
				S[ a ].merge( S[ b ] );
				break;
			case 2:
				c = r( );
				S[ a ].mergeNumber( b, c );
				break;
			case 3:
				c = r( );
				printf( "%lld\n", S[ a ].amountInSection( b, c ) );
				break;
			case 4:
				printf( "%lld\n", S[ a ].findByOrder( b ) );
				break;	
		}
		
	}
}
2020/9/21 21:39
加载中...