• 【BZOJ 2024】 2024: [SHOI2009] 舞会 (容斥原理+高精度)


    2024: [SHOI2009] 舞会

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 368  Solved: 102

    Description

    OItown要举办了一年一度的超级舞会了,作为主办方的Constantine为了使今年的舞会规模空前,他邀请了许多他的好友和同学去。舞会那天,恰好来了n个男生n个女生。Constantine发现,一般情况下,舞伴之间,总是男伴总是比女伴长得高,不过,偶尔也是有特殊情况的。所以,Constantine现在想知道,如果把这2n个人恰好配成n对舞伴,有多少种搭配方法,而且他要求最多只有k对舞伴之间女伴比男伴高。现在,Constantine需要参加SHTSC的你帮助他算出这个答案,当然啦,他会先告诉你这2n个同学的身高。

    Input

    第一行:两个整数n、k,含义如问题中所示。 第2行到第n+1行:n个整数,表示n个男生的身高。第n+2行到第2n+1行:n个整数,表示n个女生的身高。表示身高的正整数,都不超过 。

    Output

    输出文件只有一个,即满足n对舞伴中最多只有k对舞伴之间女伴比男伴高的男女搭配方案数。

    Sample Input

    3 0
    178
    188
    176
    168
    178
    170

    Sample Output

    4

    评分
    如果你的输出文件与标准答案完全相符,你将获得该测试点的全部分数,否则得零分。

    N< = 200

    K< = N

    HINT

    Source

    【分析】

      这题高精度真是太可爱了。【然后我才发现如今大概只有我这种傻逼才会用10进制的高精度,别人都是4位4位做的,搞的我RE,0msTLE,MLE都试了一通。。

      然后就是,跟“已经没有什么好害怕了”无异,具体可以看那篇。

      对于至多k,而不是恰好k,就分成恰好0+恰好1+。。。+恰好k就好了。

      【再表示一下用结构体重载运算符写高精度真的好看很多

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 210
      8 #define Maxl 210
      9 #define Mod 10000
     10 
     11 int a[Maxn],b[Maxn],mx[Maxn];
     12 
     13 struct hugeint
     14 {
     15     int w[Maxl],l;
     16     hugeint() {memset(w,0,sizeof(w));l=0;}
     17     friend hugeint operator + (hugeint x,hugeint y)
     18     {
     19         x.l=max(x.l,y.l);
     20         for(int i=0;i<=x.l;i++) x.w[i]=x.w[i]+y.w[i];
     21         for(int i=0;i<=x.l;i++) x.w[i+1]+=x.w[i]/Mod,x.w[i]%=Mod;
     22         while(x.w[x.l+1]!=0) x.w[x.l+2]+=x.w[x.l+1]/Mod,x.w[++x.l]%=Mod;
     23         while(x.w[x.l]==0&&x.l>1) x.l--;
     24         return x;
     25     }
     26     friend hugeint operator - (hugeint x,hugeint y)
     27     {
     28         for(int i=0;i<=x.l;i++) x.w[i]=x.w[i]-y.w[i];
     29         for(int i=0;i<=x.l;i++) if(x.w[i]<0) x.w[i]+=Mod,x.w[i+1]--;
     30         while(x.w[x.l]==0&&x.l>0) x.l--;
     31         return x;
     32     }
     33     friend hugeint operator * (hugeint x,hugeint y)
     34     {
     35         hugeint ret;ret.l=x.l+y.l;
     36         for(int i=0;i<=x.l;i++) for(int j=0;j<=y.l;j++) ret.w[i+j]+=x.w[i]*y.w[j];
     37         for(int i=0;i<=ret.l;i++) ret.w[i+1]+=ret.w[i]/Mod,ret.w[i]%=Mod;
     38         while(ret.w[ret.l+1]!=0) ret.w[ret.l+2]+=ret.w[ret.l+1]/Mod,ret.w[++ret.l]%=Mod;
     39         while(ret.w[ret.l]==0&&x.l>0) ret.l--;
     40         return ret;
     41     }
     42     friend hugeint operator * (hugeint x,int y)
     43     {
     44         for(int i=0;i<=x.l;i++) x.w[i]*=y;
     45         for(int i=0;i<=x.l;i++) x.w[i+1]+=x.w[i]/Mod,x.w[i]%=Mod;
     46         while(x.w[x.l+1]!=0) x.w[x.l+2]+=x.w[x.l+1]/Mod,x.w[++x.l]%=Mod;
     47         while(x.w[x.l]==0&&x.l>0) x.l--;
     48         return x;
     49     }
     50     friend bool operator > (hugeint x,hugeint y)
     51     {
     52         if(x.l!=y.l) return x.l>y.l;
     53         for(int i=x.l;i>=0;i++)
     54         {
     55             if(x.w[i]!=y.w[i]) return x.w[i]>y.w[i];
     56         }
     57     }
     58 };
     59 hugeint f[2][Maxn],c[Maxn][Maxn],fac[Maxn],g[Maxn];
     60 void clear(hugeint &x) {memset(x.w,0,sizeof(x.w));x.l=0;}
     61 
     62 int main()
     63 {
     64     int n,k;
     65     scanf("%d%d",&n,&k);
     66     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     67     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
     68     sort(a+1,a+1+n);sort(b+1,b+1+n);
     69     mx[0]=0;
     70     for(int i=1;i<=n;i++)
     71     {
     72         mx[i]=mx[i-1];
     73         while(b[i]>a[mx[i]+1]&&mx[i]<n) mx[i]++;
     74     }
     75     f[0][0].w[0]=f[1][0].w[0]=1;
     76     for(int i=1;i<=n;i++)
     77     {
     78         int p=i&1,pp=p^1;
     79         for(int j=1;j<=i;j++)
     80         {
     81             f[p][j]=f[pp][j]+f[pp][j-1]*max(mx[i]-j+1,0);
     82         }
     83     }
     84     for(int i=0;i<=n;i++) c[i][0].w[0]=1;
     85     for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) c[i][j]=c[i-1][j-1]+c[i-1][j];
     86     hugeint a1,a2,ans;
     87     fac[0].w[0]=1;
     88     for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i;
     89     for(int i=0;i<=n;i++) g[i]=f[n&1][i]*fac[n-i];
     90     for(int i=0;i<=k;i++)
     91     {
     92         clear(a1);clear(a2);
     93         for(int j=n;j>=i;j--)
     94         {
     95             if((j-i)&1) a2=a2+g[j]*c[j][i];
     96             else a1=a1+g[j]*c[j][i];
     97             if(a1>a2) {a1=a1-a2;clear(a2);}
     98         }
     99         ans=ans+(a1-a2);
    100     }
    101     printf("%d",ans.w[ans.l]);
    102     for(int i=ans.l-1;i>=0;i--) printf("%04d",ans.w[i]);printf("
    ");
    103     return 0;
    104 }
    View Code

    2017-04-20 15:29:03

  • 相关阅读:
    c copy
    IfcVertexLoop
    qt windeployqt 日志
    IfcPolyLoop
    IfcEdgeLoop
    IfcLoop
    QTableWidget
    QList删除元素
    matlab X的负次方函数绘制2
    matlab X的负次方函数绘制1
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6738995.html
Copyright © 2020-2023  润新知