• bzoj3771 Triple


    题意:你有若干把斧头,河神拿了你的1/2/3把斧头,问可能拿了你的斧头的总价值,每个总价值有多少种方案。

    斧头价值不大于40000

    解:

    很容易想到是FFT,构造函数之后A + A² + A3即可。

    然后发现漏洞百出,这道题的难点是在容斥上......

    首先只选一个的不用管了,肯定对。

    然后考虑选两个的。你直接卷积,有可能把同一把斧头选两次,还会把一个方案的两个不同排列当两次计算。

    所以我们先减去把统一斧头选两次的情况,然后把结果 / 2就是选两个的答案。

    选三个呢?我们还要构造一个函数B,代表强制把某斧头选两次,剩下的随便选。

    然后考虑选两个同样的斧头的情况:在A3中会被计算三次,因为排列有三种。在AB中会被计算一次。

    选三个同样的情况:在A3中有一次,在AB中有一次。

    三个不同的情况:在A3中有6次。在AB中没有。

    综上,可以用A3 - 3AB + 2*(每个斧头选三次) 即可。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <cmath>
      5 
      6 const int N = 250010;
      7 const double pi = 3.1415926535897932384626;
      8 
      9 struct cp {
     10     double x, y;
     11     cp(double X = 0, double Y = 0) {
     12         x = X;
     13         y = Y;
     14     }
     15     inline cp operator +(const cp &w) const {
     16         return cp(x + w.x, y + w.y);
     17     }
     18     inline cp operator -(const cp &w) const {
     19         return cp(x - w.x, y - w.y);
     20     }
     21     inline cp operator *(const cp &w) const {
     22         return cp(x * w.x - y * w.y, x * w.y + y * w.x);
     23     }
     24 }a[N], b[N], c[N];
     25 
     26 int r[N], val[N], ans[N], ans2[N];
     27 
     28 inline void FFT(int n, cp *a, int f) {
     29     for(int i = 0; i < n; i++) {
     30         if(i < r[i]) {
     31             std::swap(a[i], a[r[i]]);
     32         }
     33     }
     34     for(int len = 1; len < n; len <<= 1) {
     35         cp Wn(cos(pi / len), f * sin(pi / len));
     36         for(int i = 0; i < n; i += (len << 1)) {
     37             cp w(1, 0);
     38             for(int j = 0; j < len; j++) {
     39                 cp t = a[i + len + j] * w;
     40                 a[i + len + j] = a[i + j] - t;
     41                 a[i + j] = a[i + j] + t;
     42                 w = w * Wn;
     43             }
     44         }
     45     }
     46     if(f == -1) {
     47         for(int i = 0; i <= n; i++) {
     48             a[i].x /= n;
     49         }
     50     }
     51     return;
     52 }
     53 
     54 int main() {
     55     int n, mx = 0;
     56     scanf("%d", &n);
     57     for(int i = 1; i <= n; i++) {
     58         scanf("%d", &val[i]);
     59         a[val[i]].x += 1;
     60         b[val[i] << 1].x += 1;
     61         mx = std::max(mx, val[i]);
     62     }
     63     int len = 2, lm = 1;
     64     while(len <= mx * 3) {
     65         len <<= 1;
     66         lm++;
     67     }
     68     for(int i = 1; i <= len; i++) {
     69         r[i] = (r[i >> 1] >> 1) | ((i & 1) << (lm - 1));
     70     }
     71 
     72     FFT(len, b, 1);
     73     FFT(len, a, 1);
     74     for(int i = 0; i <= len; i++) {
     75         c[i] = a[i] * b[i];
     76         b[i] = a[i] * a[i];
     77         a[i] = a[i] * b[i];
     78     }
     79     FFT(len, a, -1); // 取三个
     80     FFT(len, b, -1); // 取两个
     81     FFT(len, c, -1); // 取三个,有两个一样
     82 
     83     for(int i = 0; i <= len; i++) {
     84         ans[i] += (int)(a[i].x + 0.5);
     85         ans[i] -= (int)(c[i].x + 0.5) * 3;
     86     }
     87     for(int i = 1; i <= n; i++) {
     88         ans[val[i] * 3] += 2;
     89         ans2[val[i] * 2]--;
     90     }
     91     for(int i = 0; i <= len; i++) {
     92         ans[i] /= 6;
     93         ans2[i] += (int)(b[i].x + 0.5);
     94         ans2[i] /= 2;
     95     }
     96 
     97     for(int i = 1; i <= n; i++) {
     98         ans[val[i]]++;
     99     }
    100 
    101     for(int i = 0; i <= len; i++) {
    102         if(ans[i] + ans2[i]) {
    103             printf("%d %d 
    ", i, ans[i] + ans2[i]);
    104         }
    105     }
    106     return 0;
    107 }
    AC代码
  • 相关阅读:
    测试websocket
    goreplay-测试app的真实流量
    apache -ab
    微信公众平台开发(69)百度地图导航
    微信公众平台开发(70)经济指标财经大事
    微信公众平台开发(68)苹果IMEI查询
    微信公众平台开发(67)百度百科
    微信公众平台开发(66)人品计算
    微信公众平台开发(65) 微博树洞
    微信公众平台开发(64)航班动态
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10265065.html
Copyright © 2020-2023  润新知