zoukankan      html  css  js  c++  java
  • HZOJ Silhouette

    转化一下题意:给出矩阵每行每列的最大值,求满足条件的矩阵个数。

    先将A,B按从大到小排序,显然没有什么影响。如果A的最大值不等于B的最大值那么无解否则一定有解。

    考虑从大到小枚举A,B中出现的数s,那么可以将这个矩形分成一些不同的矩形或者L形使之互不影响,且位置的值在[0,s]中,且每行每列的最大值均为s,最后用分步乘法计数原理求解。

    例:

    5

    1 2 2 3 5

    2 2 3 4 5

    由于矩形是特殊的L形于是我们只考虑L形:

    设拐点的矩形为a*b,L上部高为c,左部长为d。

    考虑容斥,设f[i]为至少有i行的限制不满足条件(每列都要满足条件),

    那么$f[i]=C_a^i * ( s^i * ( (s+1)^{a+c-i} - s^{a+c-i} ))^b * (s^i * (s+1)^{a-i} )^d$

    $s^i$保证i行不满足限制,$((s+1)^{a+c-i}-s^{a+c-i})$表示剩下的至少一个满足限制条件(为保证列满足),b次方即每列。这样就考虑完了前b列。

    那么多出来的d列呢?大致相同。$(s^i*(s+1)^{a-i})^d$可以发现并没有保证列满足,因为L型左部上面一定比这里大,那么已经保证列满足限制,所以这里就随便选了。

    $ans=prod sum _{i=0}^{a} -1^i*f[i]$

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #define LL long long
     6 using namespace std;
     7 const int mod=1e9+7;
     8 struct Hash_map
     9 {    
    10     int fi[233333],ni[233333],siz;
    11     int key[233333],val[233333];
    12     inline int &operator [] (int x)
    13     {
    14         int k=x%233333;int i=fi[k];
    15         for(;i&&key[i]!=x;i=ni[i]);
    16         if(!i)i=++siz,key[i]=x,val[i]=0,ni[i]=fi[k],fi[k]=i;
    17         return val[i];
    18     }
    19 }ta,tb;
    20 LL poww(LL a,LL b);
    21 LL jc[100010],inv[100010];
    22 LL CC(LL n,LL m){return jc[n]*inv[m]%mod*inv[n-m]%mod;}
    23 int n,A[100010],B[100010],C[200010],cnt;
    24 bool cmp(int a,int b){return a>b;}
    25 LL f[100010];
    26 signed main()
    27 {
    28 //    freopen("silhouette4.in","r",stdin);
    29     
    30     jc[0]=inv[0]=1;for(int i=1;i<=100000;i++)jc[i]=jc[i-1]*i%mod,inv[i]=poww(jc[i],mod-2);
    31     cin>>n;
    32     for(int i=1;i<=n;i++)cin>>A[i],C[++cnt]=A[i],ta[A[i]]++;
    33     for(int i=1;i<=n;i++)cin>>B[i],C[++cnt]=B[i],tb[B[i]]++;
    34     sort(A+1,A+n+1,cmp);sort(B+1,B+n+1,cmp);
    35     if(A[1]!=B[1]){puts("0");return 0;}
    36     sort(C+1,C+cnt+1,cmp);cnt=unique(C+1,C+cnt+1)-C-1;
    37 
    38     LL ans=1;
    39     int la=1,lb=1,na=0,nb=0;    
    40     for(int i=1;i<=cnt;i++)
    41     {    
    42         int s=C[i];
    43         la=na,lb=nb;
    44         while(na<n&&A[na+1]==s)na++;
    45         while(nb<n&&B[nb+1]==s)nb++;
    46         
    47         int a=na-la,b=nb-lb,c=la,d=lb;
    48         LL tem=0;
    49         for(int j=0;j<=a;j++)
    50         {
    51             f[j]=CC(a,j)*poww( ( poww(s,j) * (poww(s+1,a+c-j)-poww(s,a+c-j)%mod) )%mod ,b)%mod*
    52                  poww( poww(s,j)*poww(s+1,a-j)%mod ,d)%mod;
    53             if(j&1)tem-=f[j];else tem+=f[j];
    54             tem=(tem%mod+mod)%mod;
    55         }
    56         ans=(ans*tem)%mod;
    57     }
    58     printf("%lld
    ",ans);
    59 }
    60 LL poww(LL a,LL b)
    61 {
    62     a%=mod;LL ans=1;
    63     while(b)
    64     {
    65         if(b&1)ans=ans*a%mod;
    66         a=a*a%mod;b=b>>1;
    67     }
    68     return ans;
    69 }
    View Code
  • 相关阅读:
    自动杀死僵尸进程的脚本
    利用CodeBlocks修改PUTTY以文件形式保存配置信息
    [C#Util]读写文件汉字乱码
    [Hadoop]在Windows上安装Hadoop
    [短彩信]C#短彩信模块开发设计(1)——架构
    [MQ]ActiveMQ消息收发简单例子
    [C#Util]ObjectPool Prototype
    [DesignPattern]各自用一句话来概括MVC、MVP、MVVM的差异特点
    [Java]Jersey Spring Integration Demo
    [OpenSource]浅谈.Net和Java互相调用的三种方式
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11622901.html
Copyright © 2011-2022 走看看