校慶志願者小z在休息時間和同學們玩卡牌遊戲。一共有n張卡牌,每張卡牌上有乙個數ai,每次可以從中選出k張卡牌。一種選取方案的幸運值為這k張卡牌上數的異或和。小z想知道所有選取方案的幸運值之和除以998244353的餘數。
輸入的第一行有兩個整數n和k。
第二行有n個整數,表示序列a。
乙個整數表示答案。
輸入1:
3 2
1 2 3
輸入2:
10 5
123 456 789 987 654 321 101 202 303 404
輸出1:
6 輸出2:
130776
對於30%的資料滿足,1<=n<=20
對於另30%的資料滿足,1<=n<=100,0<ai<=1024
對於80%的資料滿足,1<=n<=2000
對於100%的資料滿足,1<=n<=100000,0<ai<2^31,1<=k<=n
比賽時我只打了乙個暴力,不知道為什麼還打錯了。
但是這個正解很好理解:
首先我們知道因為題目涉及到的異或運算時關於二進位制的運算,所以我們很容易想到可以把每個數分別拆成二進位制形式。因為位運算只涉及到每一位,所以直接做。
對於每一位,我們統計這些數在這一位上含有一的個數,設其為x,我們得到乙個公式: ∑i
=1kc
(x,i
)∗c(
n−x,
k−i)
∗2j
我們來理解一下這條式子。
首先,i必須是乙個奇數,因為只有有奇數個1時才可以是這一位算出來的值不為零,那麼兩個排列組合就很簡單了,那個2j
表示當前這一位為j,就是這一位的貢獻。
然後我們的排列組合因為要在模意義下,所以要用到逆元。
#include
#include
#define p 998244353
using namespace std;
int n,k;
long long ans;
long long fac[100001];
int a[100001];
long long ksm(long long xx,long long k)
returns;}
intq()
returnx;}
long long c(int n,int
m)int main()
printf("%lld\n",ans);
}
NOIP2017提高A組集訓10 21 總結
今天和學軍 雅禮的dalao們一起切磋,感覺他們太強了。接到題目 t1 一定存在著什麼規律。於是我後來打了個表找了一下規律 顯然 部分大佬們想到t1的部分分的dp 強 t2 一看就知道很可能是dp。我dp很爛,所以先打30分暴力再說。打完之後去想60分。我又根據暴力發現了在遞增序列裡,剩下的後面的數...
NOIP2017提高A組集訓10 30 總結
今天幹了些什麼 看到第一題,我蒙b了 感覺這題之前在 見過,記得好像是將圖斜過來看還是怎樣的。於是去看第二題。第二題乙個很顯然的做法,將邊排序,然後暴力建mst。然而我將時間複雜度多算了乙個0,以為不能過,結果我多加了乙個用來騙分的東西,結果這個騙分的東西打錯了,要騙分的那兩個資料都沒過。55555...
NOIP2017提高A組集訓10 22 幸運值
校慶志願者小z在休息時間和同學們玩卡牌遊戲。一共有n張卡牌,每張卡牌上有乙個數ai,每次可以從中選出k張卡牌。一種選取方案的幸運值為這k張卡牌上數的異或和。小z想知道所有選取方案的幸運值之和除以998244353的餘數。對於30 30 30 的資料滿足,1 n 20 1 le n le20 1 n ...