标签:
通道:http://acm.hdu.edu.cn/showproblem.php?pid=5307
题意:给出n个数,然后求所有的dp[i],这里的dp[i]就是所有连续区间内和为i的区间长度总和
代码:
感谢沈洋。
1 #include <cstdio> 2 3 typedef long long ll; 4 5 const int N = 262145, BUF_SIZE = N * 10, BF_LIM = 16; 6 7 namespace BF { 8 void mul(ll *a, int la, ll *b, int lb, ll *buf) { 9 int n = la + lb; 10 for (int i=0; i<n; ++i) buf[i] = 0; 11 for (int i=0; i<la; ++i) 12 for (int j=0; j<lb; ++j) 13 buf[i+j] += a[i] * b[j]; 14 } 15 } 16 namespace DAQ { 17 void _buf_mul(ll *buf, int n) { 18 int half = n >> 1, n2 = n << 1; 19 if (n <= BF_LIM) { 20 BF::mul(buf, n, buf + n, n, buf + n2); 21 for (int i=0; i<n2; ++i) 22 buf[i] = buf[i + n2]; 23 } 24 else { 25 ll *a = buf, *b = buf+half, *c = buf+n, *d = buf+n+half, 26 *r1 = buf+n2, *r2 = r1+n, *r3 = r2+n; 27 for (int i=0; i<half; ++i) 28 r1[i] = a[i], 29 r1[i+half] = c[i]; 30 _buf_mul(r1, half); 31 32 for (int i=0; i<half; ++i) 33 r2[i] = b[i], 34 r2[i+half] = d[i]; 35 _buf_mul(r2, half); 36 37 for (int i=0; i<half; ++i) 38 r3[i] = a[i] + b[i], 39 r3[i+half] = c[i] + d[i]; 40 _buf_mul(r3, half); 41 42 for (int i=0; i<n2; ++i) 43 buf[i] = 0; 44 for (int i=0; i<n; ++i) 45 buf[i] += r1[i], 46 buf[i+half] += r3[i] - r1[i] - r2[i], 47 buf[i+n] += r2[i]; 48 } 49 } 50 void mul(ll *a, int la, ll *b, int lb, ll *buf) { 51 int n; 52 for (n=1; n<la || n<lb; n<<=1); 53 for (int i=0; i<la; ++i) buf[i] = a[i]; 54 for (int i=la; i<n; ++i) buf[i] = 0; 55 for (int i=0; i<lb; ++i) buf[i+n] = b[i]; 56 for (int i=lb; i<n; ++i) buf[i+n] = 0; 57 _buf_mul(buf, n); 58 } 59 } 60 int n, m, d[N], cnt[N]; 61 ll a[N], b[N], buf[BUF_SIZE], sum[N]; 62 63 void run() { 64 scanf("%d", &n); 65 d[0] = 0; 66 for (int i=1; i<=n; ++i) scanf("%d", &d[i]), d[i] += d[i-1]; 67 m = d[n]; 68 for (int i=0; i<=m; ++i) cnt[i] = sum[i] = 0; 69 for (int i=0; i<=n; ++i) ++cnt[d[i]], sum[d[i]] += i; 70 for (int i=0; i<=m; ++i) a[i] = sum[i], b[i] = cnt[m - i]; 71 ll ans0 = 0; 72 for (int i=0; i<=m; ++i) 73 for (int j=1; j<cnt[i]; ++j) 74 ans0 += (ll)j * (cnt[i] - j); 75 DAQ::mul(a, m+1, b, m+1, buf); 76 printf("%I64d\n", ans0); 77 for (int i=1; i<=m; ++i) 78 printf("%I64d\n", buf[m + i] - buf[m - i]); 79 } 80 int main() { 81 int T; scanf("%d", &T); 82 while (T--) run(); 83 return 0; 84 }
标签:
原文地址:http://www.cnblogs.com/Rojo/p/4671560.html