zoukankan      html  css  js  c++  java
  • UVA 12633 Super Rooks on Chessboard ——FFT

    发现对角线上的和是一个定值。

    然后就不考虑斜着,可以处理出那些行和列是可以放置的。

    然后FFT,统计出每一个可行的项的系数和就可以了。

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define ll long long
    #define mp make_pair
    
    #define maxn 200005
    
    struct Complex{
    	double x,y;
    	Complex () {}
    	Complex (double _x,double _y) {x=_x;y=_y;}
    	Complex operator + (Complex a) {return Complex(x+a.x,y+a.y);}
    	Complex operator - (Complex a) {return Complex(x-a.x,y-a.y);}
    	Complex operator * (Complex a) {return Complex(x*a.x-y*a.y,x*a.y+y*a.x);}
    }A[maxn],B[maxn],C[maxn];
    
    int t,r,c,n,k,m,len,line[maxn],row[maxn],ang[maxn],rev[maxn],cntl=0,cntr=0,kas=0;
    ll ans=0;
    
    const double pi=acos(-1.0);
    
    void FFT(Complex * x,int n,int flag)
    {
    	F(i,0,n-1) if (rev[i]>i) swap(x[i],x[rev[i]]);
    	for (int m=2;m<=n;m<<=1)
    	{
    		Complex wn=Complex(cos(2*pi/m),flag*sin(2*pi/m));
    		for (int i=0;i<n;i+=m)
    		{
    			Complex w=Complex(1.0,0);
    			for (int j=0;j<(m>>1);++j)
    			{
    				Complex u=x[i+j],v=x[i+j+(m>>1)]*w;
    				x[i+j]=u+v; x[i+j+(m>>1)]=u-v;
    				w=w*wn;
    			}
    		}
    	}
    	if (flag==-1) F(i,0,n-1) x[i].x=(x[i].x+0.3)/n;
    }
    
    int main()
    {
    	scanf("%d",&t);
    	while (t--)
    	{
    		memset(line,0,sizeof line);
    		memset(row,0,sizeof row);
    		memset(ang,0,sizeof ang);
    		cntl=cntr=0;
    		scanf("%d%d%d",&r,&c,&k);
    		F(i,1,k)
    		{
    			int x,y;
    			scanf("%d%d",&x,&y);
    			x=r-x+1;
    			if (!line[x]) cntl++;
    			if (!row[y]) cntr++;
    			line[x]=1; row[y]=1;
    			ang[x+y]=1;
    		}
    		ans=((ll)r-(ll)cntl)*((ll)c-(ll)cntr);
    		n=r+c+10;m=1;len=0;
    		while (m<=n) m<<=1,len++;n=m;
    		F(i,0,n-1)
    		{
    			int ret=0,t=i;
    			F(j,1,len) ret<<=1,ret|=t&1,t>>=1;
    			rev[i]=ret;
    		}
    		F(i,0,n-1) A[i].x=B[i].x=A[i].y=B[i].y=0;
    		F(i,1,r) if (!line[i]) A[i].x=1.0;
    		F(i,1,c) if (!row[i]) B[i].x=1.0;
    		FFT(A,n,1); FFT(B,n,1);
    		F(i,0,n-1) C[i]=A[i]*B[i];
    		FFT(C,n,-1);
    		F(i,1,r+c) if (ang[i]) ans-=(ll)C[i].x;
    		printf("Case %d: ",++kas);printf("%lld
    ",ans);
    	}
    }
    

      

  • 相关阅读:
    ImportError: cannot import name 'render_to_response' 解决方法
    python 操作zookeeper详解
    Appium swipe实现屏幕滑动
    Appium 环境配置
    pytest 常用方法介绍
    Allure+pytest 生成测试报告
    Pytest 使用简介
    python 实现线程之间的通信
    python 使用 thrift 教程
    nginx 配置简单反向代理
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6776960.html
Copyright © 2011-2022 走看看