zoukankan      html  css  js  c++  java
  • UVA 12633 Super Rooks on Chessboard (生成函数+FFT)

    题面传送门

    题目大意:给你一张网格,上面有很多骑士,每个骑士能横着竖着斜着攻击一条直线上的格子,求没被攻击的格子的数量总和

    好神奇的卷积

    假设骑士不能斜着攻击

    那么答案就是没被攻击的 行数*列数

    接下来考虑斜着攻击对答案的贡献

    以左下角为坐标原点建立坐标系,发现一条对角线的点的$(x+y)$坐标是相同的

    考虑卷积,设计两个生成函数$a,b$

    如果第i行没骑士,则$a_{i}=1$,反之为$0$

    如果第i列没骑士,则$b_{i}=1$,反之为$0$

    我们对两个式子进行卷积,可以求出每一条对角线上还有多少个空格子

    答案就是$sum$ 没有骑士的对角线的空格子数

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define N1 (1<<18)
     6 #define M1 (N1<<1)
     7 #define ll long long 
     8 #define dd double
     9 #define idx(X) (X-'a')
    10 using namespace std;
    11 
    12 int gint()
    13 {
    14     int ret=0,fh=1; char c=getchar();
    15     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
    16     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
    17     return ret*fh;
    18 }
    19 int T,n,m,num,r[N1];
    20 int nt[N1],x[N1],y[N1];
    21 const dd pi=acos(-1);
    22 
    23 struct cp{
    24 dd x,y;
    25 friend cp operator + (const cp &s1,const cp &s2){ return (cp){s1.x+s2.x,s1.y+s2.y}; }
    26 friend cp operator - (const cp &s1,const cp &s2){ return (cp){s1.x-s2.x,s1.y-s2.y}; }
    27 friend cp operator * (const cp &s1,const cp &s2){ return (cp){s1.x*s2.x-s1.y*s2.y,s1.y*s2.x+s1.x*s2.y}; }
    28 }a[N1],b[N1],c[N1];
    29 
    30 void init()
    31 {
    32     memset(a,0,sizeof(a));
    33     memset(b,0,sizeof(b));
    34     memset(c,0,sizeof(c));
    35     memset(nt,0,sizeof(nt));
    36 }
    37 void FFT(cp *s,int len,int type)
    38 {
    39     int i,j,k; cp wn,w,t;
    40     for(i=0;i<len;i++) if(i<r[i]) swap(s[i],s[r[i]]);
    41     for(k=2;k<=len;k<<=1)
    42     {
    43         wn=(cp){cos(2.0*type*pi/k),sin(2.0*type*pi/k)};
    44         for(i=0;i<len;i+=k)
    45         {
    46             w=(cp){1,0};
    47             for(j=0;j<(k>>1);j++,w=w*wn)
    48             {
    49                 t=w*s[i+j+(k>>1)];
    50                 s[i+j+(k>>1)]=s[i+j]-t;
    51                 s[i+j]=s[i+j]+t;
    52             }
    53         }
    54     }
    55 }
    56 void FFT_Main(int len)
    57 {
    58     FFT(a,len,1); FFT(b,len,1);
    59     for(int i=0;i<len;i++) c[i]=a[i]*b[i];
    60     FFT(c,len,-1);
    61     for(int i=0;i<len;i++) c[i].x=c[i].x/len;
    62 }
    63 
    64 int main()
    65 {
    66     scanf("%d",&T); int t;
    67     for(t=1;t<=T;t++){
    68     
    69     init();
    70     scanf("%d%d%d",&n,&m,&num);
    71     int i,j,de,len,L; ll ans=0;
    72     for(i=1;i<=num;i++) x[i]=n-gint(), y[i]=gint()-1, a[x[i]].x=-1, b[y[i]].x=-1, nt[x[i]+y[i]]=1;
    73     for(i=0;i<n;i++) a[i].x++;
    74     for(i=0;i<m;i++) b[i].x++;
    75     for(len=1,L=0;len<n+m-1;len<<=1,L++);
    76     for(i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));
    77     FFT_Main(len);
    78     for(i=0;i<=n+m-2;i++) if(!nt[i]) ans+=(int)(c[i].x+0.1);
    79     printf("Case %d: %lld
    ",t,ans);
    80     
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    python 特性 property
    OWASP_ZAP集成渗透测试和漏洞工具
    openvas开放式漏洞评估系统
    SSL协议(安全套接层协议)
    windows下如何查看端口,关闭端口,开启端口
    网络端口通俗的说是啥意思?
    APP安全性测试总结--网上转载
    android填满手机内存的方法
    adb push和adb install区别
    Maven打包同一个jar有不同的:版本+时间戳(解决思路)
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10353513.html
Copyright © 2011-2022 走看看