题目

题目大意

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


正解

正解居然是\(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. [已解决]报错Could not install packages due to an EnvironmentError

    安装OpenCV过程中出现错误 代码: pip-conda install -i https://pypi.douban.com/simple/ opencv-python 报错内容如下: Could ...

  2. JAVA集合--Collection接口

        本文首发于cartoon的博客     转载请注明出处:https://cartoonyu.github.io/cartoon-blog     在概述里面也说过:Collection是jav ...

  3. XX Russia Team Open, High School Programming Contest St Petersburg, Barnaul, Tbilisi, Almaty, Kremenchug, November 30, 2019

    ContestLink easy: AFI medium-easy: BDH medium: CGKL ???: EJ A. Attractive Flowers 签到. B. Blocking th ...

  4. 8、如何实现可迭代对象和迭代器对象 9、如何使用生成器函数实现可迭代对象 10、如何进行反向迭代以及如何实现反向迭代 11、如何对迭代器做切片操作 12、如何在一个for语句中迭代多个可迭代对象

    8.如何实现可迭代对象和迭代器对象 PS:注意重载Iterator方法的时候,需要和原来的方法名一样,否则创建实例时会报错 from collections import Iterator,Itera ...

  5. 【踩坑】IDEA 设置 JVM 参数

    1.可视化界面设置 Run->Edit Configuration... 然后设置 2.配置文件设置 打开 IDEA 安装目录,看到有一个 bin 目录,其中有两个 vmoptions 文件,需 ...

  6. 杭电多校第一场-M-Code

    题目描述 After returning with honour from ICPC(International Cat Programming Contest) World Finals, Tom ...

  7. 笔记47 Hibernate快速入门(四)

    Hibernate注解,完成原来xml文件里的映射信息. 使用注解时,要修改hibernate.cfg.xml中的映射,不再是通过xml文件 <mapping class="hiber ...

  8. redis数据库操作

    一.String(字符串)操作 String在redis中的存储是按照key-value的形式存储 1.SET key value [EX seconds] [PX milliseconds] [NX ...

  9. wpf 绑定除数据上下文外的属性

    例如: listview 绑定了一个windows.datacontext.一个集合,那么其中一个item想绑定windows.datacontext.A属性怎么办: 通过查找祖先的方法:

  10. QTableWidget学习

    一.这次项目需要用到,可以在tablewidget中添加item,并且可以通过鼠标的右键选项进行一些打开.删除等操作. 1.在构造函数中定制右键菜单选项 ui.tableWidget_2->se ...