zoukankan      html  css  js  c++  java
  • Hackerrank--Emma and sum of products (FFT)

    题目链接

    Emma is really fond of integers and loves playing with them. Her friends were jealous, and to test her, one of them gave her a problem. 
    Emma is given a list A of N integers and is asked a set of Q queries. Each query is denoted by an integer K, for which you have to return the sum of product of all possible sublists having exactly K elements. 
    Emma has got stuck in this problem and you being her best friend have decided to help her write a code to solve it. Since the answers can be very large, print the answers modulo100003.

    Input Format
    First line has an integer N, denoting the number of integers in list A. Next line contains N space separated integers. The third line contains integer Q, and next Q lines have a single integer K.

    Output Format
    For each of the queries, print the corresponding answer in a new line.

    NOTE Sublist here refers to selecting K elements from a list of N elements. There will be (NK) ways to do that, it doesn't matter if two elements are same.

    Constraints
    1N3×104 
    1Ai105 
    1QN 
    1KN

    Sample Input #00

    3
    1 2 3
    2
    1
    2
    

    Sample Output #00

    6
    11
    

    Sample Input #01

    3
    1 2 2
    1
    2
    

    Sample Output #01

    8
    

    Explanation

    Sample #00: 
    For K=1 possible sublists are {1},{2},{3} so answer is 1+2+3=6
    For K=2 possible sublists are {1,2},{2,3},{3,1} so answer is (1×2)+(2×3)+(3×1)=2+6+3=11.

    Sample #01: 
    For K=2 possible sublists are {1,2},{2,2},{2,1} so answer is (1×2)+(2×2)+(2×1)=2+4+2=8.

    题意:给出n个数,有q次询问,每次询问一个k,从n个数中选出k个数,对这k个数做乘积,求所有可能的选法的和。

    我们把每个数看做一个多项式:x + A[i], 那么就可以得到n个这样的多项式。 将这n个多项式相乘,

    那么k对应的查询的答案就是多项式中x^k项的系数,和母函数有点类似。

    下面就是如何计算n个多项式的乘积,想到用FFT,但是不可以直接线性的计算这n个多项式的乘积,时间复杂度

    太高,所以想到分治的思想,总的复杂度就是O(n*(log(n)^2))

    Accepted Code:

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include <string>
      3 #include <vector>
      4 #include <algorithm>
      5 #include <numeric>
      6 #include <set>
      7 #include <map>
      8 #include <queue>
      9 #include <iostream>
     10 #include <sstream>
     11 #include <cstdio>
     12 #include <cmath>
     13 #include <ctime>
     14 #include <cstring>
     15 #include <cctype>
     16 #include <cassert>
     17 #include <limits>
     18 #include <bitset>
     19 #include <complex>
     20 #define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
     21 #define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
     22 #define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
     23 #define all(o) (o).begin(), (o).end()
     24 #define pb(x) push_back(x)
     25 #define mp(x,y) make_pair((x),(y))
     26 #define mset(m,v) memset(m,v,sizeof(m))
     27 #define INF 0x3f3f3f3f
     28 #define INFL 0x3f3f3f3f3f3f3f3fLL
     29 using namespace std;
     30 typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pair<int,int> > vpii;
     31 typedef long long ll; typedef vector<long long> vl; typedef pair<long long,long long> pll; typedef vector<pair<long long,long long> > vpll;
     32 typedef vector<string> vs; typedef long double ld;
     33 template<typename T, typename U> inline void amin(T &x, U y) { if(y < x) x = y; }
     34 template<typename T, typename U> inline void amax(T &x, U y) { if(x < y) x = y; }
     35 
     36 typedef long double Num;    //??????long double?????
     37 const Num PI = 3.141592653589793238462643383279L;
     38 typedef complex<Num> Complex;
     39 //n?????
     40 //a?????
     41 void fft_main(int n, Num theta, Complex a[]) {
     42     for(int m = n; m >= 2; m >>= 1) {
     43         int mh = m >> 1;
     44         Complex thetaI = Complex(0, theta);
     45         rep(i, mh) {
     46             Complex w = exp((Num)i*thetaI);
     47             for(int j = i; j < n; j += m) {
     48                 int k = j + mh;
     49                 Complex x = a[j] - a[k];
     50                 a[j] += a[k];
     51                 a[k] = w * x;
     52             }
     53         }
     54         theta *= 2;
     55     }
     56     int i = 0;
     57     reu(j, 1, n-1) {
     58         for(int k = n >> 1; k > (i ^= k); k >>= 1) ;
     59         if(j < i) swap(a[i], a[j]);
     60     }
     61 }
     62 
     63 void fft(int n, Complex a[]) { fft_main(n, 2 * PI / n, a); }
     64 void inverse_fft(int n, Complex a[]) { fft_main(n, -2 * PI / n, a); }
     65 
     66 void convolution(vector<Complex> &v, vector<Complex> &w) {
     67     int n = 1, vwn = v.size() + w.size() - 1;
     68     while(n < vwn) n <<= 1;
     69     v.resize(n), w.resize(n);
     70     fft(n, &v[0]);
     71     fft(n, &w[0]);
     72     rep(i, n) v[i] *= w[i];
     73     inverse_fft(n, &v[0]);
     74     rep(i, n) v[i] /= n;
     75 }
     76 
     77 const int MOD = 100003;
     78 
     79 vector<int> calc_dfs(const vector<int> &A, int l, int r) {
     80     if(r - l == 1) {
     81         vector<int> res(2);
     82         res[0] = 1;
     83         res[1] = A[l];
     84         return res;
     85     }
     86     int mid = (l + r) / 2;
     87     vector<int> L = calc_dfs(A, l, mid), R = calc_dfs(A, mid, r);
     88     vector<Complex> Lc(all(L)), Rc(all(R));
     89     convolution(Lc, Rc);
     90     int n = L.size() + R.size() - 1;
     91     vector<int> res(n);
     92     rep(i, n) res[i] = (long long)(Lc[i].real() + .5) % MOD;
     93 //    cerr << "["<< l << "," << r <<"): ";
     94 //    rep(i, n) cerr << res[i] << ", "; cerr << endl;
     95     return res;
     96 }
     97 
     98 int main() {
     99     int N;
    100     scanf("%d", &N);
    101     vector<int> A(N);
    102     rep(i, N) {
    103         scanf("%d", &A[i]);
    104         A[i] %= MOD;
    105     }
    106     vector<int> ans = calc_dfs(A, 0, N);
    107     int Q;
    108     scanf("%d", &Q);
    109     rep(ii, Q) {
    110         int K;
    111         scanf("%d", &K);
    112         printf("%d
    ", ans[K]);
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    bzoj 4260 Codechef REBXOR——trie树
    bzoj 2238 Mst——树链剖分
    bzoj 2836 魔法树——树链剖分
    CF 888E Maximum Subsequence——折半搜索
    bzoj 4289 PA2012 Tax——构图
    bzoj 4398 福慧双修——二进制分组
    bzoj1116 [POI2008]CLO——并查集找环
    bzoj4241 历史研究——分块
    bzoj4373 算术天才⑨与等差数列——线段树+set
    bzoj4034 [HAOI2015]树上操作——树链剖分
  • 原文地址:https://www.cnblogs.com/Stomach-ache/p/3921219.html
Copyright © 2011-2022 走看看