zoukankan      html  css  js  c++  java
  • tokiomarine2020 E O(rand)【容斥】

    传送门

    给定 (n) 元可重集合 (A) 和正整数 (k,S,T),求 (A) 有多少个 (le k) 元子集 (B) 的按位与为 (S),按位或为 (T)

    (kle nle 50,Asubseteq[0,2^{18}))


    显然可以转化为 (S=0,T=2^l-1) 的情况,其中 (l= ext{popcount}(Soplus T))

    条件即为所有位都至少出现一次但不全出现。

    容斥一下,钦定一些位要么全出现要么全不出现,设这些位是 (x),则有 (forall yin B,x&y) 都相等。

    直接暴力,时间复杂度 (O(n2^l))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 53, M = 1<<18;
    template<typename T>
    void read(T &x){
    	int ch = getchar(); x = 0;
    	for(;ch < '0' || ch > '9';ch = getchar());
    	for(;ch >= '0' && ch <= '9';ch = getchar()) x = x * 10 + ch - '0';
    } int _n, n, k, S, T, a[N], c[M]; LL F[N], C[N][N];
    int main(){
    	read(_n); read(k); read(S); read(T);
    	if((S | T) != T) return puts("0"), 0;
    	while(_n --){
    		int x; read(x);
    		if(S == (S & x) && T == (T | x)) a[++n] = x;
    	} for(int i = 0;i <= n;++ i)
    		for(int j = *C[i] = 1;j <= i && j <= k;++ j)
    			F[i] += C[i][j] = C[i-1][j] + C[i-1][j-1];
    	int _ = S ^ T; LL ans = F[n];
    	for(int u = _;u;u = u-1&_){
    		LL res = 0;
    		for(int i = 1;i <= n;++ i) ++c[a[i]&u];
    		for(int i = 1;i <= n;++ i){
    			int &tmp = c[a[i]&u];
    			res += F[tmp]; tmp = 0;
    		} ans += __builtin_popcount(u) & 1 ? -res : res;
    	} printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    HDOJ1024(最大M子段和)
    HDOJ1025(最长上升子序列)
    HDOJ1022(模拟栈)
    HDOJ(1018)
    HDOJ1238(string)
    HDOJ1015(简单深搜)
    HDOJ1016(标准dfs)
    Tabbar视图切换,返回上一视图,添加item
    页面转换方法
    网络状态判断
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/14609677.html
Copyright © 2011-2022 走看看