[UVA 12633] Super Rooks on Chessboard FFT+计数

如果只有行和列的覆盖,那么可以直接做,但现在有左上到右下的覆盖.

考虑对行和列的覆盖情况做一个卷积,然后就有了x+y的非覆盖格子数.

然后用骑士的左上到右下的覆盖特判掉那些x+y的格子就可以了.

注意题意,Row是从上到下来的,被坑得好惨.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<iomanip>
#include<algorithm>
#include<map>
using namespace std;
#define LL long long
#define FILE "dealing"
#define up(i,j,n) for(LL i=j;i<=n;++i)
#define db double
#define ull unsigned long long
#define eps 1e-10
#define pii pair<LL,LL>
LL read(){
	LL x=0,f=1,ch=getchar();
	while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
	while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
	return f*x;
}
const LL maxn=402000,maxm=20000,mod=(LL)(1e9+7+0.1),limit=(LL)(1e6+1),inf=(LL)(1e9);
bool cmax(LL& a,LL b){return a<b?a=b,true:false;}
bool cmin(LL& a,LL b){return a>b?a=b,true:false;}
namespace FFT{
	db pi=acos(-1.0);
	struct cp{
		db x,y;
		cp(db x=0,db y=0):x(x),y(y){}
		cp operator+(const cp& b){return cp(x+b.x,y+b.y);}
		cp operator-(const cp& b){return cp(x-b.x,y-b.y);}
		cp operator*(const cp& b){return cp(x*b.x-y*b.y,x*b.y+y*b.x);}
	}w[maxn],a[maxn],b[maxn];
	LL R[maxn],H,L;
	void FFT(cp* a,LL f){
		up(i,0,L-1)if(i<R[i])swap(a[i],a[R[i]]);
		for(LL len=2;len<=L;len<<=1){
			LL l=len>>1;
			cp wn(cos(pi/l),f*sin(pi/l));
			up(i,1,l-1)w[i]=w[i-1]*wn;
			for(LL st=0;st<L;st+=len)
				for(LL k=0;k<l;k++){
					cp x=a[st+k],y=w[k]*a[st+k+l];
					a[st+k]=x+y;a[st+k+l]=x-y;
				}
		}
		if(f==-1)up(i,0,L-1)a[i].x/=L;
	}
	void solve(LL* c,LL* d,LL n,LL m,LL* ch){
		n++,m++;
		up(i,0,n-1)a[i].x=c[i],a[i].y=0;
		up(i,0,m-1)b[i].x=d[i],b[i].y=0;
		for(H=0,L=1;L<n+m-1;H++)L<<=1;
		up(i,n,L)a[i].x=a[i].y=0;
		up(i,m,L)b[i].x=b[i].y=0;
		up(i,1,L)R[i]=(R[i>>1]>>1)|((i&1)<<(H-1));
		w[0].x=1;
		FFT(a,1);FFT(b,1);
		up(i,0,L-1)a[i]=a[i]*b[i];
		FFT(a,-1);
		up(i,1,n+m-1)ch[i]=(LL)(a[i].x+0.5);
	}
};
LL n,m,K;
LL a[maxn],b[maxn],c[maxn],d[maxn];
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	LL T=read();
	up(j,1,T){
		n=read(),m=read(),K=read();
		up(i,1,n)a[i]=1;
		up(i,1,m)b[i]=1;
		up(i,1,n+m)d[i]=0;
		up(i,1,K){
			LL x=n-read()+1,y=read();
			a[x]=0,b[y]=0;
			d[x+y]=1;
		}
		FFT::solve(a,b,n,m,c);
		LL ans=0;
		up(i,1,n+m)if(c[i]&&!d[i])ans+=c[i];
		printf("Case %lld: %lld\n",j,ans);
	}
	return 0;
}

  

时间: 2024-10-03 21:54:15

[UVA 12633] Super Rooks on Chessboard FFT+计数的相关文章

UVA - 12633 Super Rooks on Chessboard FFT

题目链接:点这里 题意: 给你一个矩阵R*C,n个点,与给的的n个点同一列同一行,同一条主对角线上的点都被染黑 问你最后有多少个点没有被染黑 题解: 把每一列每一行没有被染黑的x,y找出来,其任意组合起来是没这种情况下的答案(同一条主对角线上的点都被染黑) 对于 x - y,我们可以拿来判断两个点是不是相同的一条主对角线上 那么对x.-y进行任意组合,FFT加速 总的答案就是,没有被染过行数*没有被染过的列数 - (找不到相同的x- y) 具体看代码吧 #include<bits/stdc++.

UVA 12633 Super Rooks on Chessboard (生成函数+FFT)

题面传送门 题目大意:给你一张网格,上面有很多骑士,每个骑士能横着竖着斜着攻击一条直线上的格子,求没被攻击的格子的数量总和 好神奇的卷积 假设骑士不能斜着攻击 那么答案就是没被攻击的 行数*列数 接下来考虑斜着攻击对答案的贡献 以左下角为坐标原点建立坐标系,发现一条对角线的点的$(x+y)$坐标是相同的 考虑卷积,设计两个生成函数$a,b$ 如果第i行没骑士,则$a_{i}=1$,反之为$0$ 如果第i列没骑士,则$b_{i}=1$,反之为$0$ 我们对两个式子进行卷积,可以求出每一条对角线上还

HDU 4609 3-idiots(FFT计数)

题意:给n(n<=100000)根棍子.每根棍子的长度是m(m<=100000),求从中任意取出三根的概率: 题解:经典FFT计数...枚举最长边..然后经过一系列玄学取重就可以啦..好神奇呀..细节见代码. #include<bits/stdc++.h> using namespace std; #define pie acos(-1.0) const int maxn = 4e5 + 10; typedef long long ll; struct Cp{double x,y;

uva 12508 - Triangles in the Grid(几何+计数)

题目链接:uva 12508 - Triangles in the Grid 题目大意:给出n,m,A和B,要求计算在(n+1)?(m+1)的矩阵上,可以找出多少个三角形,面积在AB之间. 解题思路:首先枚举矩阵,然后计算有多少个三角形以该矩阵为外接矩阵,并且要满足体积在AB之间.然后对于每个矩阵,要确定在大的范围内可以确定几个. 枚举矩阵的内接三角形可以分为三类: 1.三角型的两点在一条矩阵边上的顶点,另一点在该边的对边上(不包括顶点) 2.以对角线为三角形的一边 这样可以枚举x,然后求出l和

UVA - 11038 How Many O&#39;s? (计数)

Description Problem E: How many 0's? A Benedict monk No. 16 writes down the decimal representations of all natural numbers between and including m and n, m ≤ n. How many 0's will he write down? Input consists of a sequence of lines. Each line contain

UVA - 11134 Fabled Rooks[贪心 问题分解]

UVA - 11134 Fabled Rooks We would like to place n rooks, 1 ≤ n ≤ 5000, on a n × n board subject to the following restrictions The i-th rook can only be placed within the rectan- gle given by its left-upper corner (xli,yli) and its right- lower corner

UVa 10161 Ant on a Chessboard

一道数学水题,找找规律. 首先要判断给的数在第几层,比如说在第n层.然后判断(n * n - n + 1)(其坐标也就是(n,n)) 之间的关系. 还要注意n的奇偶.  Problem A.Ant on a Chessboard  Background One day, an ant called Alice came to an M*M chessboard. She wanted to go around all the grids. So she began to walk along t

uva 11134 - Fabled Rooks(主要在贪心方法及其实现)

#用到了贪心方法. #这个贪心刚开始想错了方法,后来想到了新的方法,AC 刚开始错在了按左端点升序排序并从左往右取最左端能取的格子,这个方法显然不能符合要求 比如下面这组数据: 2 1 1 3 3 1 1 3 3 2 2 2 2 错误代码: #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; struct note {

UVA 12298 Super Poker II (FFT)

#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int N = 1000005; const long double pi = acos(-1.0); struct Complex { long double r,i; Complex(long double r=0, long double i=0):r(r),