解题报告:HDU_4093 Xavier is Learning to Count FFT
来源:互联网 发布:mac照片拷贝变小 编辑:程序博客网 时间:2024/06/03 15:02
题目链接
题意:
给定一个长度为n的数列,选其中p个数相加,要求输出可以得到所有结果和得到方案数。
思路:
不写了。。。贴代码留恋。。。写的难受,一直MLE,还卡精度,这题出现在现场赛里。。有毒
#include<bits/stdc++.h>const long double PI = acos(-1.0);using namespace std;struct comple{ long double r , i; comple(long double rr=0,long double ii=0){ r = rr; i = ii; }comple operator + (const comple& a){ return comple(r+a.r,i+a.i); }comple operator - (const comple& a){ return comple(r-a.r,i-a.i); }comple operator * (const comple& a){ return comple(r*a.r-i*a.i , r*a.i+i*a.r); }};int getLen(int x){ int res = 1; while(res<x)res<<=1; return res;}void brc(comple *a,int l){ for(int i=1,j=l/2;i<l-1;i++){ if(i<j)swap(a[i],a[j]); int k = l/2; while(j>=k){ j-=k; k>>=1; }if(j<k)j+=k; }}void fft(comple *y,int l,int on){ brc(y,l); comple u,t; for(int h=2;h<=l;h<<=1){ comple wn( cos(on*2*PI/h),sin(on*2*PI/h) ); for(int j=0;j<l;j+=h){ comple w(1,0); for(int k=j;k<j+h/2;k++){ u = y[k]; t = w*y[k+h/2]; y[k] = u+t; y[k+h/2] = u-t; w = w*wn; } } }if(on<0){ for(int i=0;i<l;i++){ y[i].r/=l; } }}const int MAXL = (1<<16);int n;int A[13005];comple F[12][MAXL];long long tmp[12][MAXL];void dfs(int now , int need ,const int& l){ if(now>need)return ; if(now==1){ for(int i=0;i<13001;i++){ F[10][i<<2].r = F[1][i<<1].r = F[4][i*3].r = F[0][i].r = tmp[10][i<<2] = tmp[1][i<<1] = tmp[4][i*3] = tmp[0][i] = A[i]; tmp[11][i*5]=A[i]; if(now==need){ if(tmp[0][i])printf("%d: %I64d\n",i,tmp[0][i]); } }return dfs(now+1,need,l); } if(now==2){ fft(F[0],l,1); for(int i=0;i<l;i++){ F[2][i] = F[0][i] * F[0][i]; }fft(F[2],l,-1); for(int i=0;i<l;i++){ tmp[2][i] = (long long)(F[2][i].r+0.5); F[2][i].i = 0; tmp[2][i] = (tmp[2][i]+tmp[1][i])/2; F[2][i].r = tmp[2][i]; if(now==need){ long long ans = tmp[2][i] - tmp[1][i]; if(ans)printf("%d: %I64d\n",i,ans); } }return dfs(now+1,need,l); }if(now==3){ fft(F[2],l,1);fft(F[1],l,1); for(int i=0;i<l;i++){ F[5][i] = F[0][i] * F[2][i]; F[3][i] = F[0][i] * F[1][i]; }fft(F[3],l,-1);fft(F[5],l,-1); for(int i=0;i<l;i++){ F[3][i].i = F[5][i].i = 0; tmp[3][i] = (long long)(F[3][i].r+0.5); F[3][i].r = tmp[3][i]; tmp[5][i] = (long long)(F[5][i].r+0.5); tmp[5][i] = ( tmp[5][i] + tmp[3][i] + tmp[4][i] ) / 3; F[5][i].r = tmp[5][i]; if(now==need){ long long ans = (tmp[5][i] - tmp[3][i]); if(ans)printf("%d: %I64d\n",i,ans); } }return dfs(now+1,need,l); }if(now==4){ fft(F[4],l,1);fft(F[5],l,1);fft(F[10],l,1); for(int i=0;i<l;i++){ F[6][i] = F[5][i] * F[0][i]; F[7][i] = F[1][i] * F[2][i]; F[8][i] = F[1][i] * F[1][i]; F[9][i] = F[4][i] * F[0][i]; }fft(F[6],l,-1);fft(F[7],l,-1);fft(F[8],l,-1);fft(F[9],l,-1); for(int i=0;i<l;i++){ F[6][i].i = F[7][i].i = F[8][i].i = F[9][i].i = 0; tmp[6][i] = (long long)(F[6][i].r+0.5); tmp[7][i] = (long long)(F[7][i].r+0.5); tmp[8][i] = (long long)(F[8][i].r+0.5); tmp[8][i] = (tmp[8][i]+tmp[10][i])/2; tmp[9][i] = (long long)(F[9][i].r+0.5); tmp[6][i] = (tmp[6][i]+tmp[7][i]+tmp[9][i]+tmp[10][i])/4; if(now==need){ long long ans = ( tmp[6][i] - tmp[7][i] + tmp[8][i] - tmp[10][i] ); if(ans)printf("%d: %I64d\n",i,ans); } F[6][i].i = 0; F[6][i].r = tmp[6][i]; F[8][i].r = tmp[8][i]; }return dfs(now+1,need,l); }if(now==5){ fft(F[6],l,1);fft(F[8],l,1); for(int i=0;i<l;i++){ F[6][i] = F[6][i] * F[0][i]; F[7][i] = F[1][i] * F[5][i]; F[9][i] = F[0][i] * F[8][i]; F[8][i] = F[4][i] * F[2][i]; F[3][i] = F[10][i] * F[0][i]; }fft(F[7],l,-1);fft(F[8],l,-1); fft(F[9],l,-1);fft(F[6],l,-1); fft(F[3],l,-1); for(int i=0;i<l;i++){ tmp[6][i] = (long long)(F[6][i].r+0.5); tmp[7][i] = (long long)(F[7][i].r+0.5); tmp[8][i] = (long long)(F[8][i].r+0.5); tmp[9][i] = (long long)(F[9][i].r+0.5); tmp[3][i] = (long long)(F[3][i].r+0.5); long long cnt = (tmp[6][i]+tmp[7][i]+tmp[8][i]+tmp[3][i]+tmp[11][i]); tmp[6][i] = cnt/5; if(now==need){ long long ans = tmp[6][i] - tmp[7][i] + tmp[9][i]-tmp[3][i]; if(ans)printf("%d: %I64d\n",i,ans); } }return dfs(now+1,need,l); }}int main(){ int T,k,t=0; scanf("%d",&T); while(T--){ printf("Case #%d:\n",++t); scanf("%d%d",&n,&k); memset(A,0,sizeof(A)); memset(tmp,0,sizeof(tmp)); memset(F,0,sizeof(F)); int l = 0; for(int i=0,x;i<n;i++){ scanf("%d",&x); l = max(l,x); A[x]++; }l = l * k ; l = getLen(l); dfs(1,k,l); printf("\n"); }return 0;}
阅读全文
0 0
- 解题报告:HDU_4093 Xavier is Learning to Count FFT
- HDU 4093 2011上海区域赛 Xavier is Learning to Count (FFT+容斥原理)
- Hdu 4093 ( Xavier is Learning to Count ) BZOJ2498 FFT+容斥原理
- HDU 4093 Xavier is Learning to Count FFT + 容斥原理 2011年上海现场赛C题
- [bzoj3956]Count 解题报告
- bzoj3956 Count 解题报告
- [bzoj4664] Count 解题报告
- 2777 Count Color 解题报告
- HDU Count 101 解题报告
- LeetCode-Count Primes-解题报告
- 【LeetCode】 Count Primes 解题报告
- Count Primes [LeetCode 解题报告]
- 解题报告:Arithmetic Progressions 分块+FFT
- bzoj4259残缺的字符串FFT解题报告
- HDU Count the Trees 解题报告
- LeetCode Count and Say 解题报告
- 解题报告 之 HOJ2276 SOJ2498 Count prime
- LeetCode-Count Complete Tree Nodes -解题报告
- 请求参数乱码
- Android开发——使用ActivityLifecycleCallbacks监控App是否处于后台
- sql where 1=1和 0=1 的作用
- Springboot整合kafka
- MaterialDrawer+ToolBar飘逸的导航和抽屉侧滑(用户登录信息的抽屉布局)
- 解题报告:HDU_4093 Xavier is Learning to Count FFT
- 母函数
- (51)线程间通信,等待唤醒机制
- 动态sql标签trim的用法
- JZOJ100042. 【NOIP2017提高A组模拟7.12】保留道路
- [Lintcode]翻转链表
- JQuery学习笔记
- Ajax诠释
- 初始化与清除