D. Ones and Twos CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!)逆向思维

逆向思维
† An array b is a subarray of an array a if b can be obtained from a by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end. In particular, an array is a subarray of itself.
题目为了降低难度,给了提示,考虑一个子序列sum=x,我们可以查询子序列的反y=query-x,为什么呢,因为对于一个y来说,分奇偶可以很方便的查询,因为过于简单,读者思考一下就知道了(这其实启示我们对于一个子序列的操作,一种经典的解决方法是逆向思维)
Ac_code:

# include  <bits/stdc++.h>
using  namespace  std ;

using ll = int64_t ;

namespace predefine {
const long long inf = 0x3f3f3f3f3f3f3f3f ;
using Int = __int128 ;
using pll = pair < ll , ll > ;
# define  IOS  iostream::sync_with_stdio ( 0 ) ; cin.tie ( 0 ) ;

# define af( i , a , b ) for ( ll i = a ; i <= b ; ++ i )
# define df( i , a , b ) for ( ll i = a ; i >= b ; -- i )

# define Dg( x ) cout << " ------- " <<  x << " ------- " << '\n'
# define Dged Dg ( "Debug ed" )
# define Dgop Dg ( "Debug op" )
# define pr( x ) cout << #x << " = " << x << '\n'
# define pn putchar ('\n') 
# define ps cout << "yes" 
# define __fin( a ) freopen ( a , "r" , stdin ) 
# define __fout( a ) freopen ( a , "w+" , stdout ) 

# define lowbit( x ) ( x & ( - x ) ) 
}
using namespace predefine ;


//-----  板子  ---------------------------------------------------------------------------------------------------------

//-----  板子  ---------------------------------------------------------------------------------------------------------


ll Pow ( ll a , ll b , ll mod ) { 
	a = a % mod ; ll ans = 1 ; 
	for ( ; b ; b >>= 1 ) { if ( b & 1 ) ans = ( a * ans ) % mod ; a = ( a * a ) % mod ; } 
	return ans ; }

inline ll sum1 ( ll _a ) { return ( _a * ( _a + 1 ) ) >> 1 ; }
inline ll sum2 ( ll _b ) { return _b * ( _b + 1 ) * ( 2 * _b + 1 ) / 6  ; }

ll dx [ 4 ] = { -1 , 0 , 1 , 0 } ;
ll dy [ 4 ] = { 0 , 1 , 0 , -1 } ;

// using ll = long long ;!!!

void solve () {
	ll n , m ; cin >> n >> m ;
	ll sum = 0 ;
	vector < ll > v ( n ) ;
	set < ll > s ;
	af ( i , 0 , n - 1 ) cin >> v [ i ] , sum += v [ i ] ;
	af ( i , 0 , n - 1 ) if ( v [ i ] == 1 ) {
		s.emplace ( i ) ;
	}
	auto get = [ & ] () {
		if ( s.empty () ) return inf ;
		else {
			ll l = ( * ( s.begin () ) ) + 1 ;
			ll r = ( * ( s.rbegin () ) ) + 1 ;
			ll min = std::min ( 2 * ( l - 1 ) + 1 , 2 * ( n - r ) + 1 ) ;
			return min ;
		}
	};
	af ( i , 1 , m ) {
		ll op ; cin >> op ;
		if ( op == 1 ) {
			ll x ; cin >> x ;
			if ( x > sum ) {
				cout << "NO" << endl ;
				continue ;
			}
			ll y = sum - x ;
			if ( ( y & 1 ) == 0 ) {
				cout << "YES" << endl ;
				continue ;
			}
			else {
				if ( y >= get () ) cout << "YES" << endl ;
				else cout << "NO" << endl ;
			}
		}
		else {
			ll pos , change ; cin >> pos >> change ; -- pos ;
			if ( v [ pos ] == change ) continue ;
			v [ pos ] = change ; 
			if ( change == 2 ) {
				++ sum ; s.erase ( pos ) ;
			}
			else {
				-- sum , s.emplace ( pos ) ;
			}
//			Dgop ;
//			for ( auto u : v ) cout << u << ' ' ;
//			cout << endl ;
//			Dged ; 
		}
	}
}

int  main () {
//	__fin ( "in.in" ) ;
	ll _ = 1 ;
	// rd ( _ ) ;
   	cin >> _ ;
	while ( _ -- ) {
		solve () ;
	} 
	return 0 ;
}

/*
//-----  数据  ---------------------------------------------------------------------------------------------------------


1
4 31
1 1 1 1 
1 7
2 1 1
1 5
2 2 2
1 1
2 1 2
1 6
2 3 2
1 7
2 1 2
1 2
2 2 1
1 3
2 1 1
1 5
2 4 1
1 3
2 1 1
1 1
2 2 2
1 6
2 1 2
1 1
2 3 2
1 6
2 1 2
1 1
2 2 1
1 7
2 1 1
1 4
----------
*/
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值