一中模擬賽11.2——Alice的幸運數
阿新 • • 發佈:2018-12-13
Solution
引理1:當 時全用 能使最小值為
個 能使 的個數減半,而 個數最多 個 ,所以 個數能使 的個數為
引理2: 操作能被 操作代替
0^0=0;0&~0=0
0^1=1;0&~1=0
1^0=1;1&~0=1
1^1=0;1&~1=0
比較左右兩列,發現
操作一定
操作
引理3:只用 一定能得到最優解
把
個數二進位制展開,可以得到一個大小為
的表:
把它豎著看,每列看作一個狀態,不管用什麼運算子,相同狀態的最終結果一定相同
首先假設狀態數大於
,因為狀態數
時三種操作都可以做到
用
可以得到只有一個狀態最終結果為
要證明的就是
、
、
三種操作混合不能使
種不同狀態均為
假設有一個長度為
的
序列,每兩個數之間的操作相同,注意到不管是哪種操作,最終結果都是
或
(且都能取到),於是長度為
的混合序列可以看作若干個這樣的序列(相當於縮點),最終結果是
或
(都能取到)
只用引理1已經能過了這題,但時間複雜度為 ,引理2能優化到 ,引理3能優化到
Code
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
int T,n,i,s;
ll a[101],ans,t;
int main(){
for (scanf("%d",&T);T--;){
scanf("%d",&n);
for (i=0;i<n;i++) scanf("%llu",&a[i]);
if (n>6){
puts("0");
continue;
}
ans=~0;
for (s=0;s<1<<n;s++,ans=min(ans,t))
for (i=0,t=~0;i<n;i++) t&=(s&(1<<i)?a[i]:~a[i]);
printf("%llu\n",ans);
}
}