description
传送门
给个数,让你输出所有可能的由三个不同下标的数得到的和,以及构成该和的方案数。
solution
很容易想到卷三次,但要减掉存在至少两个相同下标的方案。
因此构造,因此即为三个或两个下标都相同的方案1。
思考怎么容斥的时候分类讨论算凑目标贡献。
首先,熟悉的套路:选择的三元组可以按照排列做贡献,最后除以。
中三个下标相同的算了一次,而恰两个下标相同的算了三次。
因此多减两个三个下标相同的,构造 。
所以最终答案为:
code
戳我
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e6+5;
const db pi=acos(-1);
struct cop {
db img,rl;
friend inline cop operator*(cop u,cop v) {return (cop){u.img*v.rl+u.rl*v.img,u.rl*v.rl-u.img*v.img};}
friend inline cop operator+(cop u,cop v) {return (cop){u.img+v.img,u.rl+v.rl};}
friend inline cop operator-(cop u,cop v) {return (cop){u.img-v.img,u.rl-v.rl};}
}A[N],B[N],C[N],K[N];
int up,rev[N];
void gt_up(int len) {
up=1;int l=0;
while(up<=len)up<<=1,l++;
for(int i=1;i<up;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
}
void FFT(cop *a,int op) {
for(int i=1;i<up;i++)if(rev[i]>i)swap(a[i],a[rev[i]]);
for(int mid=1;mid<up;mid<<=1) {
cop w1=(cop){op*sin(pi/mid),cos(pi/mid)};
for(int len=mid<<1,l=0;l<up;l+=len) {
cop w=(cop){0,1};
for(int i=0;i<mid;i++,w=w*w1) {
int p=l+i,q=p+mid;
cop x=a[p],y=a[q]*w;
a[p]=x+y;a[q]=x-y;
}
}
}
}
int b[N],mn=114514,mx=-mn;
int main() {
int n;scanf("%d",&n);
for(int i=1;i<=n;i++) {scanf("%d",&b[i]);mx=max(mx,b[i]);mn=min(mn,b[i]);}
if(mn<0) {
mn*=-1;mx+=mn;
for(int i=1;i<=n;i++)b[i]+=mn;
}
else mn=0;
// printf("!");
gt_up(mx*3);
for(int i=1;i<=n;i++) {A[b[i]].rl++;B[b[i]<<1].rl+=3;C[b[i]*3].rl+=2;}
FFT(A,-1);FFT(B,-1);FFT(C,-1);
for(int i=0;i<up;i++)A[i]=A[i]*A[i]*A[i]-A[i]*B[i]+C[i];
FFT(A,1);
for(int i=0;i<3*mx;i++) {
ll val=(ll)round(A[i].rl/up);
if(!val)continue;
printf("%d : %lld\n",i-3*mn,val/6);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人