• 玛里苟斯[清华集训2014 Day1]


    玛里苟斯[清华集训2014 Day1]

    魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心,于是他想了一道数学题。

    S 是一个可重集合,S={a1,a2,,an}

    等概率随机取 S 的一个子集 A={ai1,,aim}

    计算出 A 中所有元素异或 x, 求 xk 的期望。

    SOL :

    这题目太色情了。没打高精度炸的不要不要的。

     我们观察一波局势,发现当K=1时我们可以按位异或,我们可以证明,若 S集合中存在X 在 i位是1,那么这一位上出现1的期望就是0.5.

      证明如下,我们把每一位上的ai的值取出来,那么我们发现0对答案没有贡献。设我们有X个1,而我们取偶数个1的期望为 signma C(2i+1,x)=((1+1)^n+(1-1) ^ n)/2;

    而总数为2^n,那么我们的期望就是0.5.

    所以我们统计每一位上是否有1,最后累加除2.

    K=2:我们依旧统计每一位上是否有1.

     我们发现我们得到每一位上有1的位对答案

       ∑j=0mp=0m(2ni=1bi,jbi,p2n2j+p)

    我们就可以将其答案统计出来。

    K>2 我们惊奇的发现,对S其进行求线性基其答案不变。我们发现K>2时由于答案在LongLong范围内,我们可以保证求出得基最多22个,

    暴力统计答案即可。

    #pragma optimize("-O2")
    #include<bits/stdc++.h>
    #define sight(c) ('0'<=c&&c<='9')
    #define LL unsigned long long
    #define N 100009
    #define db long double
    const LL mo=(1<<25)-1;
    using namespace std;
    struct NL{
        LL a,b;
        NL() {a=b=0;}
        NL(LL x,LL y):a(x),b(y){}
        inline NL operator ^(const NL &A)const &{
           return NL(A.a^a,A.b^b);
        }
        inline NL operator ^(const LL &A)const &{
           return NL(a,A^b);
        }
        inline NL operator +(const NL &A)const &{
           NL T;
           T.a=A.a+a; T.b=A.b+b;
           if (T.b>mo) T.a+=T.b>>25,T.b&=mo;
           return T;
        }
        inline NL operator +(const LL &A)const &{
           NL T; T.a=a; T.b=A+b;
           if (T.b>mo) T.a+=T.b>>25,T.b&=mo;
           return T;
        }
        inline NL operator *(const NL &A)const &{
           NL T;
           T.a=(A.a*a<<25)+A.a*b+A.b*a; T.b=A.b*b;
           if (T.b>mo) T.a+=T.b>>25,T.b&=mo;
           return T;
        }
        inline NL operator *(const LL &A)const &{
           NL T;
           T.a=a*A; T.b=A*b;
           if (T.b>mo) T.a+=T.b>>25,T.b&=mo;
           return T;
        }
        inline LL ok(int x){
            LL T=b&(1ll<<x)-1;
            b>>=x; b|=(a&(1ll<<x)-1)<<(25-x);a>>=x;
            return T;
        }
    };
    inline void read(LL &x){
        static char c;
        for (c=getchar();!sight(c);c=getchar());
        for (x=0;sight(c);c=getchar()) x=x*10+c-48;
    }
    void write(LL x) {
        if (x<10) { putchar('0'+x); return;} write(x/10); putchar('0'+x%10);
    }
    inline void writeln(LL x) {
        if (x<0) putchar('-'),x*=-1; write(x); putchar('
    ');
    }
    LL n,k,ans,X,A[N],P[65],r,OT[65],O;
    NL Ans;
    void Guass()
    {
        for (int i=1;i<=n;i++)
         for (int j=62;~j;j--)
            if ((A[i]>>j)&1) 
             if (!P[j]) {P[j]=A[i]; break;} 
             else A[i]^=P[j];
        for (int j=0;j<=62;j++) if (P[j]) OT[r++]=P[j];
    }
    int b[79];
    inline NL pow(NL x,int k){
        NL anw=NL(0,1);
        for (;k;k>>=1,x=x*x)if (k&1) anw=anw*x;
        return anw;
    }
    void dfs(NL x,int t){
        if (!(t^r)) { Ans=Ans+pow(x,k); return;} 
        dfs(x^OT[t],t+1);  dfs(x,t+1);
    }
    int main () {    
        freopen("malygos.in","r",stdin);
        freopen("malygos.out","w",stdout);
        read(n); read(k);
        for (int i=1;i<=n;i++) {
          read(A[i]); 
          for (int j=0;j<=63;j++) b[j]|=(A[i]>>j)&1;
        }
        if (k==1) {
          for (int j=63;~j;j--) if (b[j]) ans+=1ll<<j; 
           write(ans>>1); if (ans&1) puts(".5
    "); return 0;
        }
        if (k==2) {
            for (int j=31;~j;j--) if (b[j]) Ans=Ans+(1ull<<2*j+1);
            for (int i=31;~i;i--) {
            for (int j=0;j<i;j++) {
                int c[4]={};
                for (int k=1;k<=n;k++)  c[(A[k]>>i&1)<<1|(A[k]>>j&1)]=1;
                for (int k=0;k<4;k++) 
                    for (int ii=0;ii<4;ii++) 
                        for (int jj=0;jj<4;jj++) if (c[ii]&&c[jj])  c[ii^jj] = 1;
                int s=0;
                for (int k=0;k<4;k++) s+=c[k];
                if (c[3])     Ans=Ans+((LL)(8/s)*(1ULL<<i+j));
            }}
            LL g=Ans.ok(2);
            LL T=(Ans.a<<25)+Ans.b;
            write(T);
            LL MM=1<<2;
            if (g) {
                putchar('.');
                while (g) {g*=10; putchar('0'+g/MM); g%=MM;}
            }
            return 0;
        }
        Guass();
        dfs(NL(0,0),0);
        LL g=Ans.ok(r);
        LL T=(Ans.a<<25)+Ans.b;
        write(T);
        LL MM=1<<r;
        if (g) {
            putchar('.');
            while (g) {
                g*=10; putchar('0'+g/MM); g%=MM;}
        }
        return 0;
    }
  • 相关阅读:
    从0开始学习C#第三天
    金盾视频加密器V2014视频加密原理分析
    从0开始学习C#第二天
    从0开始学习C#第一天
    hook NtTerminateProcess进行应用的保护
    Wireshark简单使用教程3——附视频
    Wireshark简单使用教程2——附视频
    Wireshark简单使用教程1——附视频
    一个bat病毒分析(part1)
    社团的CTF逆向题WriteUp
  • 原文地址:https://www.cnblogs.com/rrsb/p/8260454.html
Copyright © 2020-2023  润新知