题意:给定标号从1到n的n个点,链接两个点x,y的代价为x AND y,求最小生成树总代价与满足代价最小的前提下字典序最小的方案
n<=2e5
思路:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 #define N 4100 10 #define M 4100000 11 #define fi first 12 #define se second 13 #define MP make_pair 14 #define pi acos(-1) 15 #define mem(a,b) memset(a,b,sizeof(a)) 16 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 17 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 18 #define lowbit(x) x&(-x) 19 #define Rand (rand()*(1<<16)+rand()) 20 #define id(x) ((x)<=B?(x):m-n/(x)+1) 21 #define ls p<<1 22 #define rs p<<1|1 23 24 const ll MOD=998244353,inv2=(MOD+1)/2; 25 double eps=1e-6; 26 int INF=1e9; 27 28 29 int read() 30 { 31 int v=0,f=1; 32 char c=getchar(); 33 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 34 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 35 return v*f; 36 } 37 38 int check(int x) 39 { 40 int t=x&(-x); 41 if(t==x) return 1; 42 return 0; 43 } 44 45 46 int main() 47 { 48 //freopen("1.in","r",stdin); 49 //freopen("1.out","w",stdout); 50 int cas=read(); 51 int mx=(1<<20)-1; 52 while(cas--) 53 { 54 int n=read(); 55 if(check(n+1)) 56 { 57 printf("1 "); 58 rep(i,2,n-1) 59 { 60 int t=i^mx; 61 //printf("t=%d ",t); 62 t=lowbit(t); 63 //printf("lowbit=%d ",t); 64 printf("%d ",t); 65 } 66 printf("1 "); 67 } 68 else 69 { 70 printf("0 "); 71 rep(i,2,n) 72 { 73 int t=i^mx; 74 t=lowbit(t); 75 if(i<n) printf("%d ",t); 76 else printf("%d",t); 77 } 78 printf(" "); 79 } 80 } 81 return 0; 82 }