瞎搞居然1A,真是吃鲸
n的范围只有聪明人能看见……建议读题3遍 首先看计数就想到生成函数,列出多项式A(x),然后分别考虑123 对于选一个的直接计数即可; 对于选两个的,\( A(x)^2 \),然后注意这里两个选一样的是不合法的,各出现了一次,所以减掉,然后这里是有顺序的,所以最后再除以2(就是(1,2)和(2,1)算两次); 对于选三个的,\( A(x)^3 \),然后去掉不合法的,设D(x)为每个斧头选两次的生成函数(也就是价格*2),然后A(x)*D(x)就表示前两个斧头重复选取的方案,注意是前两个,然后类似的情况还有后两个斧头重复选取的方案,第一个第三个斧头重复选取的方案,所以每一项*3,答案减掉这个多项式,然后发现三个斧头都选一样的情况各被算了三遍,所以再加上即可#include#include #include using namespace std;const int N=500005;int n,m,lm,bt,ans[N],re[N],x[N],q[N];struct cd{ double a,b; cd(double A=0,double B=0) { a=A,b=B; } cd operator + (const cd &x) const { return cd(a+x.a,b+x.b); } cd operator - (const cd &x) const { return cd(a-x.a,b-x.b); } cd operator * (const cd &x) const { return cd(a*x.a-b*x.b,a*x.b+b*x.a); }}a[N],b[N],c[N],d[N],e[N];int read(){ int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } return r*f;}void dft(cd a[],int f){ for(int i=0;i >1]>>1)|((i&1)<<(bt-1)); fft(a,b); for(int i=0;i