@description@

在三维空间内有 N 个不同的点,请计算下面式子的值 Q 次:

\[\sum_{i\not = j}\frac{|A(x_i-x_j) + B(y_i-y_j) + C(z_i - z_j) + D|}{N*(N-1)*\sqrt{(x_i-x_j)^4 + (y_i-y_j)^4 + (z_i-z_j)^4}}
\]

其中 A、B、C 和 D 在每次计算中都会被重新指定。

输入格式

输入数据第一行包含两个整数 N 和 Q,分别表示点的数量和询问的次数。

接下来的 N 行,每行包含三个整数 Xi、Yi 和 Zi 表示点坐标。

接下来的 Q 行,每行包含 4 个整数 A、B、C 和 D,表示一次询问。

输出格式

对于每次询问,输出一行包含相应的答案,精确到 10^(−6) 以上。

数据范围

• 2 ≤ N ≤ 777777

• 1 ≤ Q ≤ 77

• 1 ≤ Xi,Yi,Zi ≤ 77

• 1 ≤ Ai,Bi,Ci ≤ 77

• 1 ≤ Di ≤ 7777

• 愿数字 7 给你带来好运

样例数据

输入

10 5

45 70 41

9 1 43

1 68 8

70 76 7

1 19 33

71 70 53

42 54 71

11 13 30

16 63 25

30 24 34

56 61 29 7328

63 32 18 365

37 41 11 2332

36 19 43 7432

68 55 46 6338

输出

6.692386875130186

1.323651551014940

2.269817185835997

6.783038317971530

5.816449269601737

@solution@

还以为是什么神仙推式子数学题。。。结果没想到就是道 sb 题 -_-。。。

考虑题目给定的式子,实际上与 xi, xj 这些变量无关而只与 (xi - xj), (yi - yj), (zi - zj) 这三个量有关。

于是我们只需要统计各个三元组分别的出现次数,就可以在 (77*2)^3 时间内完成一次询问。

考虑在一维的时候,实际上就是给你 n 个不同的数 x[1...n],对于每个非零的 a 求 \((\sum_{x[i]-x[j]=a}1)\)。

woc 这么像一个卷积,那我们就构造一个卷积得了。

令 \(f(p) = \sum_{i=1}^{n}p^{x_i}, g(p) = \sum_{i=1}^{n}p^{-x_i}\),把 f 和 g 作卷积就好了。

负指数幂加一个常数就变成正指数了。

三维的就用高维卷积,实际上就是把它转为 2*77 进制数,最低位为 x,次第位为 y,以此类推。

因为点互不相同,所以一个点对一个三元组的贡献最多为 1,那么答案不超过 N。所以 ntt 不会产生问题。

时间复杂度 O((77*2)^3*q + (77*2)3*log((77*2)3))

@accepted code@

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int G = 3;
const int MOD = 998244353;
const int N = 77;
const int M = 4194304;
int pow_mod(int b, int p) {
int ret = 1;
while( p ) {
if( p & 1 ) ret = 1LL*ret*b%MOD;
b = 1LL*b*b%MOD;
p >>= 1;
}
return ret;
}
int pw[25], ipw[25];
void ntt(int *A, int len, int type) {
for(int i=0,j=0;i<len;i++) {
if( i < j ) swap(A[i], A[j]);
for(int k=(len>>1);(j^=k)<k;k>>=1);
}
for(int i=1;(1<<i)<=len;i++) {
int s = (1<<i), t = (s>>1);
int u = (type == 1 ? pw[i] : ipw[i]);
for(int j=0;j<len;j+=s) {
for(int k=0,p=1;k<t;k++,p=1LL*p*u%MOD) {
int x = A[j+k], y = 1LL*A[j+k+t]*p%MOD;
A[j+k] = (x + y)%MOD, A[j+k+t] = (x + MOD - y)%MOD;
}
}
}
if( type == -1 ) {
int inv = pow_mod(len, MOD-2);
for(int i=0;i<len;i++)
A[i] = 1LL*A[i]*inv%MOD;
}
}
void init() {
for(int i=0;i<25;i++)
pw[i] = pow_mod(G, (MOD - 1)/(1<<i)), ipw[i] = pow_mod(pw[i], MOD - 2);
}
int n, q;
double a, b, c, d;
double pw4(double x) {
return x*x*x*x;
}
double func(double x, double y, double z) {
return fabs(a*x + b*y + c*z + d)/sqrt(pw4(x) + pw4(y) + pw4(z))/n/(n-1);
}
int A[2*N + 5][2*N + 5][2*N + 5], B[2*N + 5][2*N + 5][2*N + 5], C[2*N + 5][2*N + 5][2*N + 5];
int f[M], g[M];
int main() {
init(); scanf("%d%d", &n, &q);
for(int i=1;i<=n;i++) {
int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z);
X--, Y--, Z--; A[X][Y][Z]++;
}
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++)
B[i][j][k] = A[N-i-1][N-j-1][N-k-1];
for(int i=0;i<2*N-1;i++)
for(int j=0;j<2*N-1;j++)
for(int k=0;k<2*N-1;k++)
f[(i*(2*N-1) + j)*(2*N-1) + k] = A[i][j][k], g[(i*(2*N-1) + j)*(2*N-1) + k] = B[i][j][k];
ntt(f, M, 1), ntt(g, M, 1);
for(int i=0;i<M;i++)
f[i] = 1LL*f[i]*g[i]%MOD;
ntt(f, M, -1);
for(int i=0;i<2*N-1;i++)
for(int j=0;j<2*N-1;j++)
for(int k=0;k<2*N-1;k++)
C[i][j][k] = f[(i*(2*N-1) + j)*(2*N-1) + k];
/*
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++)
for(int p=0;p<N;p++)
for(int q=0;q<N;q++)
for(int r=0;r<N;r++)
C[i+p][j+q][k+r] = (C[i+p][j+q][k+r] + 1LL*A[i][j][k]*B[p][q][r]%MOD)%MOD;
*/
for(int i=1;i<=q;i++) {
scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
double ans = 0;
for(int i=-(N-1);i<=N-1;i++)
for(int j=-(N-1);j<=N-1;j++)
for(int k=-(N-1);k<=N-1;k++)
if( (i || j || k) && C[N-1+i][N-1+j][N-1+k] )
ans += C[N-1+i][N-1+j][N-1+k]*func(i, j, k);
printf("%.10lf\n", ans);
}
}

@details@

其实高维卷积还可以通过一维一维的 ntt 来搞,这样子 log 会小些,但是边长会由 77*2 变为 256,反而会慢些。

看来以后想题不能直接想复杂的,要坚定地认为“既然出题人出得出来那它一定可以做”。

@codechef - MGCH3D@ 3D Queries的更多相关文章

  1. CodeChef DISTNUM2 Easy Queries 节点数组线段树

    Description You are given an array A consisting of N positive integers. You have to answer Q queries ...

  2. codechef Tree and Queries Solved

    题目链接: https://www.codechef.com/problems/IITK1P10 大概是:修改点值,求子树节点为0有多少个, DFS序后,BIT 询问,修改 ;    {        ...

  3. scau 2015寒假训练

    并不是很正规的.每个人自愿参与自愿退出,马哥找题(马哥超nice么么哒). 放假第一周与放假结束前一周 2015-01-26 http://acm.hust.edu.cn/vjudge/contest ...

  4. CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries

    https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...

  5. [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)

    [BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...

  6. Codechef Dynamic Trees and Queries

    Home » Practice(Hard) » Dynamic Trees and Queries Problem Code: ANUDTQSubmit https://www.codechef.co ...

  7. 【CodeChef】Chef and Graph Queries

    Portal --> CC Chef and Graph Queries Solution 快乐数据结构题(然而好像有十分优秀的莫队+可撤销并查集搞法qwq) 首先考虑一种方式来方便一点地..计 ...

  8. [CodeChef - GERALD07 ] Chef and Graph Queries

    Read problems statements in Mandarin Chineseand Russian. Problem Statement Chef has a undirected gra ...

  9. CodeChef Gcd Queries

    Gcd Queries   Problem code: GCDQ   Submit All Submissions   All submissions for this problem are ava ...

随机推荐

  1. 【Ruby】与ruby相关的内容

    本博文是为了记录Ruby相关的可学习资源,以便日常使用 在线学习Rails的网站版本 Ruby on Rails教程(Rails 5) Ruby的中文社区 Ruby China

  2. input只能输入数字和小数点,并且只能保留小数点后两位 - CSDN博客

    1.给文本框添加一个onkeyup=’clearNoNum(this)’点击事件 2.建立clearNoNum方法 function clearNoNum(obj) { obj.value = obj ...

  3. 当移动数据分析需求遇到Quick BI

    我叫洞幺,是一名大型婚恋网站“我在这等你”的资深老员工,虽然在公司五六年,还在一线搬砖.“我在这等你”成立15年,目前积累注册用户高达2亿多,在我们网站成功牵手的用户达2千多万.目前我们的公司在CEO ...

  4. 警告: deleting object of polymorphic class type which has non_virtual destructor

    如果基类里有虚函数,定义了基类指针指向派生类,就会需要定义基类虚析构,这样,基类指针析构的时候,就会先析构派生类,再析构基类. 在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,d ...

  5. 前端框架中 “类mixin” 模式的思考

    "类 mixin" 指的是 Vue 中的 mixin,Regular 中的 implement 使用 Mixin 的目的 首先我们需要知道为什么会有 mixin 的存在? 为了扩展 ...

  6. python装饰器2

    装饰模式有很多经典的使用场景,例如插入日志.性能测试.事务处理等等,有了装饰器,就可以提取大量函数中与本身功能无关的类似代码,从而达到代码重用的目的.下面就一步步看看Python中的装饰器. 一个简单 ...

  7. 50倍时空算力提升,阿里云RDS PostgreSQL GPU版本上线

    2019年3月19日,阿里云RDS PostgreSQL数据库GPU规格版本正式上线,开启了RDS异构计算并行加速之路.该版本在RDS(关系型数据库服务)的云基础设施层面首次完成了与阿里云异构计算产品 ...

  8. MySQL安装后设置root 密码

    Mysql安装完成后初始化root 密码为空,直接回车 使用命令行: mysqladmin -u root password "123456" 来设置root密码.这里我设置的密码 ...

  9. 10分钟学会Python

    #1. 语法 Python中没有强制的语句终止字符,代码块是通过缩进来指示的.缩进表示一个代码块的开始,逆缩进则表示一个代码块的结束.一般用4个空格来表示缩进. 声明以冒号(:)字符结束,并且开启一个 ...

  10. 一句python,一句R︱python中的字符串操作、中文乱码、NaN情况

    一句python,一句R︱python中的字符串操作.中文乱码.NaN情况 先学了R,最近刚刚上手Python,所以想着将python和R结合起来互相对比来更好理解python.最好就是一句pytho ...