题目

题目大意

也懒得解释题目大意了……


正解

正解居然是\(FFT\)?

不要看题目的那个式子这么长,也不要在那个式子上下手。

其实我们会发现,不同的\((x_i-x_j,y_i-y_j,z_i-z_j)\)并不多。

如果我们求出每个三元组的出现次数,后面的就好做了。

那怎么求呢?

祭出我们的大杀器——\(FFT\)。

考虑只有一个维怎么做。设两个多项式分别为\(A\)和\(B\)。

对于\(x_i\),就在\(A\)的\(x_i\)这一位上的系数加一;

对于\(x_j\),就在\(B\)的\(77-x_j\)这一位上的系数加一。

将\(A\)和\(B\)乘起来,那么\(77+x_i-x_j\)就是差\(x_i-x_j\)对应的个数。

对于三维,就将这三个数压成一维的就好了。

实际上也可以用NTT。仔细分析一下,就可以发现每个三元组的出现次数肯定是不超过\(998244353\)的。


正解

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <cmath>
#define N 1000000
#define MX 3652264
#define mo 998244353
inline int input(){
char ch=getchar();
while (ch<'0' || '9'<ch)
ch=getchar();
int x=0;
do{
x=x*10+ch-'0';
ch=getchar();
}
while ('0'<=ch && ch<='9');
return x;
}
inline int my_pow(int x,int y){
int res=1;
for (;y;y>>=1,x=(long long)x*x%mo)
if (y&1)
res=(long long)res*x%mo;
return res;
}
inline int pow4(int x){x*=x;return x*x;}
#define M (1<<22)
#define bit 22
int n;
struct DOT{
int x,y,z;
inline DOT rev(){return {77-x,77-y,77-z};}
} d[N];
inline int pia(const DOT &a){return (a.x*154+a.y)*154+a.z;}
int a[1<<22],b[1<<22],cnt[1<<22];
int rev[1<<22];
inline void ntt(int *a,int flag){
for (int i=0;i<M;++i)
if (i<rev[i])
swap(a[i],a[rev[i]]);
for (int i=1;i<M;i<<=1){
int wn=my_pow(3,(mo+1)/(i<<1));
if (flag==-1)
wn=my_pow(wn,mo-2);
for (int j=0;j<M;j+=i<<1){
int wnk=1;
for (int k=j;k<j+i;++k,wnk=(long long)wnk*wn%mo){
int x=a[k],y=(long long)wnk*a[k+i]%mo;
a[k]=(x+y>=mo?x+y-mo:x+y);
a[k+i]=(x-y<0?x-y+mo:x-y);
}
}
}
if (flag==-1){
int invm=my_pow(M,mo-2);
for (int i=0;i<M;++i)
a[i]=(long long)a[i]*invm%mo;
}
}
inline void multi(int *a,int *b,int *c){
for (int i=1;i<M;++i)
rev[i]=rev[i>>1]>>1|(i&1)<<bit-1;
ntt(a,1),ntt(b,1);
for (int i=0;i<M;++i)
c[i]=(long long)a[i]*b[i]%mo;
ntt(c,-1);
}
DOT back[M];
int main(){
freopen("geometry.in","r",stdin);
freopen("geometry.out","w",stdout);
int Q;
scanf("%d%d",&n,&Q);
for (int i=1;i<=n;++i)
d[i]={input(),input(),input()};
for (int i=1;i<=n;++i){
a[pia(d[i])]++;
b[pia(d[i].rev())]++;
}
multi(a,b,cnt);
for (int i=0;i<MX;++i){
int j=i;
back[i].z=j%154-77;j/=154;
back[i].y=j%154-77;j/=154;
back[i].x=j-77;
// assert(pia(back[i])==i);
}
while (Q--){
int a=input(),b=input(),c=input(),d=input();
double ans=0;
for (int i=0;i<MX;++i)
if (cnt[i] && (back[i].x|back[i].y|back[i].z))
ans+=(long long)cnt[i]*abs(a*back[i].x+b*back[i].y+c*back[i].z+d)/sqrt(pow4(back[i].x)+pow4(back[i].y)+pow4(back[i].z));
ans/=(long long)n*(n-1);
printf("%.10lf\n",ans);
}
return 0;
}

总结

\(FFT\)和\(NTT\)真是个bug般的存在……

[JZOJ4330] 【清华集训模拟】几何题的更多相关文章

  1. [JZOJ4331] 【清华集训模拟】树

    题目 题目大意 给你一棵带点权的树,求将树变成一堆不相交的链,而且这些链的权值和非负的方案数. 正解 显然这道题是个\(DP\). 首先求个前缀和\(sum\). 为了后面讲述方便,我这样设:\(f_ ...

  2. UOJ_274_[清华集训2016]温暖会指引我们前行_LCT

    UOJ_274_[清华集训2016]温暖会指引我们前行_LCT 任务描述:http://uoj.ac/problem/274 本题中的字典序不同在于空串的字典序最大. 并且题中要求排序后字典序最大. ...

  3. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

  4. 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)

    [UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...

  5. 【UOJ274】【清华集训2016】温暖会指引我们前行 LCT

    [UOJ274][清华集训2016]温暖会指引我们前行 任务描述 虽然小R住的宿舍楼早已来了暖气,但是由于某些原因,宿舍楼中的某些窗户仍然开着(例如厕所的窗户),这就使得宿舍楼中有一些路上的温度还是很 ...

  6. uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题

    [清华集训2014]矩阵变换 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出 ...

  7. loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主

    #2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较   题目描述 "A fight? Co ...

  8. [LOJ#2329]「清华集训 2017」我的生命已如风中残烛

    [LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...

  9. [LOJ#2328]「清华集训 2017」避难所

    [LOJ#2328]「清华集训 2017」避难所 试题描述 "B君啊,你当年的伙伴都不在北京了,为什么你还在北京呢?" "大概是因为出了一些事故吧,否则这道题就不叫避难所 ...

随机推荐

  1. python调用tushare获取IPO新股上市列表数据

    接口:new_share 描述:获取新股上市列表数据 限量:单次最大2000条,总量不限制 积分:用户需要至少120积分才可以调取,具体请参阅本文最下方积分获取办法 注:tushare包下载和初始化教 ...

  2. python--模块导入与执行

    定义:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 一.模块注意: 1.所有的模块都应该自觉的往上写 2.调用模块的时候都是最先在本地找 3.写模块的顺序是 ...

  3. Unity 中调用Android的JAVA代码

    首先我们要创建一个android项目 因为项目需要使用Unity提供的接口,所以需要将接口classes.jar引入至当前工程但中.接口包的所在地,打开Finder->应用程序->Unit ...

  4. JavaWeb学习篇之----EL表达式详解

    我们之前的几篇文章中都提到了一个EL表达式,那么这个EL表达式到底是什么东东呢?为什么用处那么大,下面我们就来看看EL表达式的相关内容 EL表达式简介: EL 全名为Expression Langua ...

  5. Python self的用法

    1)不加self是局部变量,只在这个方法里有效:加self则是实例变量,相当于别的函数定义的变量你实例化出来就可以使用 #coding:utf-8 class Person: def __init__ ...

  6. [转]gulp打包工具总结

    与grunt类似,gulp也是构建工具,但相比于grunt的频繁IO操作,gulp的流操作能更快更便捷地完成构建工作.gulp借鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级 ...

  7. sqlserver 调优(二)

    良好的系统和数据库设计,优质的SQL编写,合适的数据表索引设计,甚至各种硬件因素:网络性能.服务器的性能.操作系统的性能,甚至网卡.交换机等.这篇文章主要讲到如何改善SQL语句,还将有另一篇讨论如何改 ...

  8. python从入门到大神---1、初始化实例、类属性、方法

    python从入门到大神---1.初始化实例.类属性.方法 一.总结 一句话总结: 方法不加括号是代码段:感觉python方法和js,php很类似,不加括号是代码段,加括号变成方法,比如f,f() 1 ...

  9. 转-C/C++ new与malloc区别

    1.属性 new/delete是C++关键字,需要编译器支持.malloc/free是库函数,需要头文件支持. 2.参数 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计 ...

  10. chomp

    用来除去最后的换行等空白字符. 例程: #!/usr/bin/perl #chomp.pl use warnings; use strict; print "Input a string & ...