Codeforces- 1547D-Co-growing Sequence
Codeforces- 1547D-Co-growing Sequence
题目大意:
又是一道位运算啊,为什么位运算的题目都是酱紫绕来绕去的?这题是这样的:
对长度为n的数组a,满足a[i] = a[i] & a[i - 1],即后一个和当前的与等于当前,就称a数组“grow”。
对两个长度为n的数组a、b,每一位两两亦或得到新的数组c,若数组c是“grow”的那就称a、b是“co-grow”的。
现给你一个a数组,请求出字典序最小的b数组。
思路:
要字典序最小,b的第一个元素一定是0。a数组是确定的,而b[0]是确定的0,所以c[0]是确定的,即b[0]^0 = b[0]。ok,有了第一个c,我们就可以开始贪了:)。
对于每一个c[i-1],他的二进制位j若是1,那c[i]的对应j位也一定要是1 。(因为要满足c的“grow”要求)。
cij= 1的话,就要看已经确定了的a来判断bij 。而若c[i-1][j]为0的话,cij可0可1,对应的bij直接置0即可。
代码实现:
#include<bits/stdc++.h>
#define debug cout<<"= =\n"
#define pii pair< int , int >
#define pll pair< long long , long long >
/*
=========> A Tyrion Project .
*/
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f;
const ll N = 2*1e6+1000;
const ll mod = 1e9 + 7 ;
/////////////////////////////////////////////////
int n , tmp ;
vector<bitset<30> >a , b , c ;
void solve(){
int n , a , b , c ;
cin>>n>>c ;
cout<<"0 " ;
for(int i = 2 ; i <= n ; i ++ ){
cin>>a ; b = 0 ;
for(int j = 0 ; j < 30 ; j ++ ){
int posa = a & (1 << j) ;
int posc = c & (1 << j) ;
if(posc && !posa)b += (1 <<j) ;
}
cout<<b<<" " ;
c = a ^ b ;
}
cout<<"\n" ;
}
int main(){
ios::sync_with_stdio(false) ;
//freopen("inn.in","r",stdin) ;
ll T ;
cin>>T ;
while(T -- )solve() ;
}
写在后面:
一开始想用bitset做的,然后发现用bitset还要把二进制转回来好麻烦,就用上述代码中的方式来遍历二进制的每一位。

浙公网安备 33010602011771号