bzoj3771 Triple

mac2022-07-05  36

题目链接

bzoj3771 Triple 粘一下题面吧还是qwqqqqq,挺好玩的 我们讲一个悲伤的故事。 从前有一个贫穷的樵夫在河边砍柴。 这时候河里出现了一个水神,夺过了他的斧头,说: “这把斧头,是不是你的?” 樵夫一看:“是啊是啊!” 水神把斧头扔在一边,又拿起一个东西问: “这把斧头,是不是你的?” 樵夫看不清楚,但又怕真的是自己的斧头,只好又答:“是啊是啊!” 水神又把手上的东西扔在一边,拿起第三个东西问: “这把斧头,是不是你的?” 樵夫还是看不清楚,但是他觉得再这样下去他就没法砍柴了。 于是他又一次答:“是啊是啊!真的是!” 水神看着他,哈哈大笑道: “你看看你现在的样子,真是丑陋!” 之后就消失了。 樵夫觉得很坑爹,他今天不仅没有砍到柴,还丢了一把斧头给那个水神。 于是他准备回家换一把斧头。 回家之后他才发现真正坑爹的事情才刚开始。 水神拿着的的确是他的斧头。 但是不一定是他拿出去的那把,还有可能是水神不知道怎么偷偷从他家里拿走的。 换句话说,水神可能拿走了他的一把,两把或者三把斧头。 樵夫觉得今天真是倒霉透了,但不管怎么样日子还得过。 他想统计他的损失。 樵夫的每一把斧头都有一个价值,不同斧头的价值不同。总损失就是丢掉的斧头价值和。 他想对于每个可能的总损失,计算有几种可能的方案。 注意:如果水神拿走了两把斧头a和b,(a,b)和(b,a)视为一种方案。拿走三把斧头时,(a,b,c),(b,c,a),(c,a,b),(c,b,a),(b,a,c),(a,c,b)视为一种方案。

题解

所谓形式幂级数,字面意思理解嘛 构造生成函数A\(\{0,x^{w_1},...x^{w_2},...x^{w_n}\}\) 幂为价值,洗漱为方案数 那么 , \(A^2\) 便是两两组合两种的情况,\(A^3\)便是三三 题目要求无顺序,每一种情况除一个阶乘,然后发现有重复取得情况如\(\{xx\}\{xxy\}\) 构造一个某把斧头钦定选两次的生成函数B:\(\{0,x^{2w_1},...x^{2w_2},...x^{2w_n}\}\) 三次的C:\(\{0,x^{3w_1},...x^{3w_2},...x^{3w_n}\}\) 对于两斧组合,同一个被选了两次,直接减去B 那么A*B便是包含两个重复斧头的三斧方案,这种组合有3种排列方式\(\{xyx\}\{xxy\}\{yxx\}\)所以需要减去\(3*A*B\)\(\{xxx\}\)只有一种,多减了两次,便再\(+2*C\) fft优化一下

代码

#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> inline int read() { int x = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c <= '9' && c >= '0')x = x * 10 + c- '0',c = getchar(); return x ; } #define pi acos(-1.0) struct Complex { double x,y; Complex(double a = 0,double b = 0) : x(a),y(b) {}; } ; Complex operator + (Complex a,Complex b) { return Complex(a.x + b.x,a.y + b.y);} Complex operator - (Complex a,Complex b) { return Complex(a.x - b.x,a.y - b.y);} Complex operator * (Complex a,Complex b) { return Complex(a.x * b.x - a.y * b.y,a.x * b.y + a.y * b.x);} const int maxn = 1000007; int n; Complex A[maxn],B[maxn],C[maxn]; void fft(Complex *a,int n,int type) { for(int i = 0,j = 0;i < n;++ i) { if(i < j) std::swap(a[i],a[j]); for(int k = n >> 1;(j ^= k) < k;k >>= 1); } for(int m = 2;m <= n;m <<= 1) { Complex w1 = Complex (cos(2 * pi / m),type * sin(2 * pi / m)); for(int i = 0;i < n;i += m) { Complex w = Complex(1,0); for(int k = 0;k < (m >> 1);++ k) { Complex t = w * a[i + k + (m >> 1)],u = a[i + k]; a[i + k] = u + t; a[i + k + (m >> 1)] = u - t; w = w * w1; } } } } Complex ans[maxn]; int main() { n = read(); int lim = 0; for(int tmp,i = 1;i <= n;++ i) { tmp = read(); A[tmp] = Complex(1,0); B[tmp * 2] = Complex(1,0); C[tmp * 3] = Complex(1,0); lim = std::max(lim,tmp * 3); } for(n = 1;n <= lim;n <<= 1); fft(A,n,1); fft(B,n,1); fft(C,n,1); for(int i = 0;i < n;++ i) ans[i] = A[i] + (A[i] * A[i] - B[i]) * Complex(1.0 / 2.0,0) + (A[i] * A[i] * A[i] - A[i] * B[i] * Complex(3.0,0) + Complex(2.0,0) * C[i]) * Complex(1.0 / 6.0,0); fft(ans,n,-1); for(int i = 0;i < n;++ i) { int T = ans[i].x / n + 0.5; if(T) printf("%d %d\n",i,T); } return 0; }

转载于:https://www.cnblogs.com/sssy/p/9177769.html

相关资源:25个经典网站源代码
最新回复(0)