【学习笔记】CF1770F Koxia and Sequence

发现每个位置是等价的,这样如果 n n n为偶数那么答案是 0 0 0,否则为所有方案数中 a 1 a_1 a1的异或和

发现题目设计的非常巧妙,加上 ( OR i = 1 n a i ) ⊆ y (\text{OR}_{i=1}^n a_i)\subseteq y (ORi=1nai)y 的限制过后,变量的取值就有了范围,我们可以利用这一条件对式子进行化简

考虑钦定 a 1 a_1 a1的第 k k k位为 1 1 1,然后计算方案数为: ∑ ∑ a i = x − 2 k [ a 1 ⊆ y − 2 k ] [ a 2 ⊆ y ] . . . [ a n ⊆ y ] = ∑ ∑ a i = x − 2 k ( y − 2 k a 1 ) ( y a 2 ) . . . ( y a n ) = ( n y − 2 k x − 2 k ) = [ ( x − 2 k ) ⊆ ( n y − 2 k ) ] \begin{aligned}&\sum_{\sum a_i=x-2^k}[a_1\subseteq y-2^k][a_2\subseteq y]...[a_n\subseteq y] \\ &= \sum_{\sum a_i=x-2^k}\binom{y-2^k}{a_1}\binom{y}{a_2}...\binom{y}{a_n} \\&= \binom{ny-2^k}{x-2^k} \\&=[(x-2^k)\subseteq (ny-2^k)]\end{aligned} ai=x2k[a1y2k][a2y]...[any]=ai=x2k(a1y2k)(a2y)...(any)=(x2kny2k)=[(x2k)(ny2k)]

可以 O ( 1 ) O(1) O(1)计算。最后枚举 y y y的子集容斥计算即可。

复杂度 O ( y log ⁡ y ) O(y\log y) O(ylogy)

代码真的很短

#include
#define fi first
#define se second
#define pb push_back
#define db double
#define ll long long
#define ull unsigned long long
using namespace std;
ll n,x,y,res;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>x>>y;
    if(n%2==0){
        cout<<0;
        return 0;
    }
    for(ll i=y;i;i=(i-1)&y){
        for(int j=0;j<20;j++){
            if(i>>j&1){
                ll a=x-(1<<j),b=n*i-(1<<j);
                if(a>=0&&b>=0&&(a&b)==a){
                    res^=(1<<j);
                }
            }
        }
    }cout<<res;
}

你可能感兴趣的:(学习,笔记)