• BZOJ3771: Triple【生成函数】


    Description

    我们讲一个悲伤的故事。

    从前有一个贫穷的樵夫在河边砍柴。

    这时候河里出现了一个水神,夺过了他的斧头,说:

    “这把斧头,是不是你的?”

    樵夫一看:“是啊是啊!”

    水神把斧头扔在一边,又拿起一个东西问:

    “这把斧头,是不是你的?”

    樵夫看不清楚,但又怕真的是自己的斧头,只好又答:“是啊是啊!”

    水神又把手上的东西扔在一边,拿起第三个东西问:

    “这把斧头,是不是你的?”

    樵夫还是看不清楚,但是他觉得再这样下去他就没法砍柴了。

    于是他又一次答:“是啊是啊!真的是!”

    水神看着他,哈哈大笑道:

    “你看看你现在的样子,真是丑陋!”

    之后就消失了。

    樵夫觉得很坑爹,他今天不仅没有砍到柴,还丢了一把斧头给那个水神。

    于是他准备回家换一把斧头。

    回家之后他才发现真正坑爹的事情才刚开始。

    水神拿着的的确是他的斧头。

    但是不一定是他拿出去的那把,还有可能是水神不知道怎么偷偷从他家里拿走的。

    换句话说,水神可能拿走了他的一把,两把或者三把斧头。

    樵夫觉得今天真是倒霉透了,但不管怎么样日子还得过。

    他想统计他的损失。

    樵夫的每一把斧头都有一个价值,不同斧头的价值不同。总损失就是丢掉的斧头价值和。

    他想对于每个可能的总损失,计算有几种可能的方案。

    注意:如果水神拿走了两把斧头a和b,(a,b)和(b,a)视为一种方案。拿走三把斧头时,(a,b,c),(b,c,a),(c,a,b),(c,b,a),(b,a,c),(a,c,b)视为一种方案。

    Input

    第一行是整数N,表示有N把斧头。

    接下来n行升序输入N个数字Ai,表示每把斧头的价值。

    Output

    若干行,按升序对于所有可能的总损失输出一行x y,x为损失值,y为方案数

    Sample Input

    4
    4
    5
    6
    7

    Sample Output

    4 1
    5 1
    6 1
    7 1
    9 1
    10 1
    11 2
    12 1
    13 1
    15 1
    16 1
    17 1
    18 1
    样例解释
    11有两种方案是4+7和5+6,其他损失值都有唯一方案,例如4=4,5=5,10=4+6,18=5+6+7.

    HINT

    所有数据满足:Ai<=40000


    思路

    考虑一个两个三个分别的生成函数

    容斥掉不合法贡献


    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int N = 3e5 + 10;
    const double eps = 1e-6;
    const double PI = acos(-1);
    
    typedef complex<double> Complex;
    
    Complex f[N], g[N], h[N], p[N], q[N], w[N][2];
    
    void init() {
      for (int i = 1; i < (1 << 18); i <<= 1) {
        w[i][0] = w[i][1] = Complex(1, 0);
        Complex wn(cos(PI / i), sin(PI / i));
        for (int j = 1; j < i; j++)
          w[i + j][1] = w[i + j - 1][1] * wn;
        wn = Complex(cos(PI / i), -sin(PI / i));
        for (int j = 1; j < i; j++)
          w[i + j][0] = w[i + j - 1][0] * wn;
      }
    }
    
    void transform(Complex t[N], int len, int typ) {
      for (int i = 0, j = 0, k; j < len; j++) {
        if (i > j) swap(t[i], t[j]);
        for (k = (len >> 1); k & i; k >>= 1) i ^= k;
        i ^= k; 
      }
      for (int i = 1; i < len; i <<= 1) {
        for (int j = 0; j < len; j += (i << 1)) {
          for (int k = 0; k < i; k++) {
            Complex x = t[j + k], y = t[j + k + i] * w[i + k][typ];
            t[j + k] = x + y;
            t[j + k + i] = x - y;
          }
        }
      }
      if (typ) return;
      for (int i = 0; i < len; i++)
        t[i] = Complex(t[i].real() / (double) len, t[i].imag());
    }
    
    int n, a[N];
    
    int main() {
    #ifdef dream_maker
      freopen("input.txt", "r", stdin);
    #endif
      init();
      int maxval = 0;
      scanf("%d", &n);
      for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        maxval = max(maxval, a[i]);
      }
      maxval = maxval * 3 + 1;
      for (int i = 1; i <= n; i++) {
        f[a[i]] = Complex(f[a[i]].real() + 1, f[a[i]].imag());
        p[a[i] * 2] = Complex(p[a[i] * 2].real() + 1, p[a[i] * 2].imag());
        q[a[i] * 3] = Complex(q[a[i] * 3].real() + 1, q[a[i] * 3].imag());
      }
      int len = 1 << (int) ceil(log2(maxval * 2 - 1));
      transform(f, len, 1);
      for (int i = 0; i < len; i++)
        g[i] = f[i] * f[i];
      transform(g, len, 0);
      for (int i = 0; i < len; i++)
        g[i] -= p[i];
      transform(g, len, 1);
      for (int i = 0; i < len; i++)
        h[i] = f[i] * f[i] * f[i];
      transform(h, len, 0);
      transform(p, len, 1);
      for (int i = 0; i < len; i++)
        p[i] = f[i] * p[i];
      transform(g, len, 0);
      transform(f, len, 0);
      transform(p, len, 0);
      for (int i = 0; i <= len; i++) {
        h[i] -= p[i] + p[i] + p[i];  
        h[i] += q[i] + q[i];
      }
      for (int i = 0; i <= maxval; i++)
        if ((int) (round(f[i].real()) + round(g[i].real()) / 2 + round(h[i].real()) / 6))
          printf("%d %d
    ", i, (int) (round(f[i].real()) + round(g[i].real()) / 2 + round(h[i].real()) / 6));
      return 0;
    } 
    
  • 相关阅读:
    DLL内存加载
    Intel汇编程序设计-高级过程(上)
    Intel汇编程序设计-高级过程(上)
    C#-常用
    C#-常用
    C#-MD5
    C#-MD5
    C#-文件操作
    POJ 3320 Jessica's Reading Problem
    POJ 2456 Aggressive cows
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/10241065.html
Copyright © 2020-2023  润新知