• [bzoj3198] [Sdoi2013]spring


    Description

    img

    Input

    img

    Output

    img

    Sample Input

    3 3 
    1 2 3 4 5 6
    1 2 3 0 0 0
    0 0 0 4 5 6
    

    Sample Output

    2
    

    HINT

    img

    Dragonite修正数据

    题解

    前置知识:广义容斥原理

    由于是要求恰好k个满足的方案数,考虑容斥。

    设$alpha (x) $表示至少满足有x个相等的方案数,答案即为:

    [sum _{i=k}^n(-1)^{i-k}inom{i}{k}alpha (i) ]

    然后对于(alpha (x)),可以直接用(Hash\_Table)求。

    #pragma GCC optimize(3)
    #include<bits/stdc++.h>
    using namespace std;
     
    #define int long long
     
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
     
    void print(int x) {
        if(x<0) x=-x,putchar('-');
        if(!x) return ;print(x/10),putchar(x%10+'0');
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
     
    #define maxn 2000050
     
    int binom(int n,int m) {
        int res=1;for(int i=1;i<=m;i++) res=res*(n-i+1);
        for(int i=1;i<=m;i++) res=res/i;return res;
    }
     
    int n,k,a[maxn][7];
     
    const int mod=1e6+19,base=10;
     
    struct Hash_Table {
        int head[mod+1],nxt[maxn],val[maxn][7],sum[maxn],tot;
        int insert(int p,int s) {
            int hs=0;
            for(int i=0;i<6;i++) if((s>>i)&1) hs=(hs*base+a[p][i+1])%mod;
            for(int i=head[hs];i;i=nxt[i]) {
                int cnt=0,bo=1;//write(hs);
                for(int j=1;j<=6;j++) if((s>>(j-1))&1) if(val[i][++cnt]!=a[p][j]) bo=0;
                if(bo) return sum[i]++;
            }
            nxt[++tot]=head[hs],head[hs]=tot;val[tot][0]=0;
            for(int i=1;i<=6;i++) if((s>>(i-1))&1) val[tot][++val[tot][0]]=a[p][i]; 
            sum[tot]++;return 0;
        }
        void clear() {
            tot=0;memset(head,0,sizeof head);
            memset(sum,0,sizeof sum);
        }
    }Hash;
     
    int calc(int s) {
        int l=__builtin_popcount(s),ans=0;
        if(l<k) return 0;
        Hash.clear();
        for(int i=1;i<=n;i++) ans+=Hash.insert(i,s);
        ans*=(((l-k)&1)?-1:1)*binom(l,k);
        //if(ans) printf("%d %d
    ",s,ans);
        return ans;
    }
     
    signed main() {
        read(n),read(k);
        for(int i=1;i<=n;i++) for(int j=1;j<=6;j++) read(a[i][j]);
        int ans=0;
        for(int i=0;i<(1<<6);i++) ans+=calc(i);
        write(ans);//Hash.debug();
        //cerr << (double) clock()/CLOCKS_PER_SEC << endl;
        return 0;
    }
    
  • 相关阅读:
    YARN源码学习(七)-----Task级别GC相关指标的自定义counter添加
    YARN源码学习(七)-----Task级别GC相关指标的自定义counter添加
    YARN源码分析(八)-----Reduce Shuffle过程分析
    YARN源码分析(八)-----Reduce Shuffle过程分析
    【每天一道算法题】整数循环节之和——数字黑洞6174
    getline函数
    设计模式之建造者模式Builder(创建型)
    字符串算法总结
    C++设计模式之单例模式
    Linux下C的线程同步机制
  • 原文地址:https://www.cnblogs.com/hbyer/p/10030067.html
Copyright © 2020-2023  润新知