首页 > 代码库 > 【FFT】OpenJ_POJ - C17H - Reverse K-th Problem
【FFT】OpenJ_POJ - C17H - Reverse K-th Problem
对每个位置i处理出以其为结尾,且比a(i)大的数有j个的前缀个数,记成一个数组l;同理,处理出以其为开头,且比a(i)大的数有j个的后缀的个数,记成一个数组r。
整个序列中比a(i)大的数的个数的数组就是对l和r数组卷积起来。
于是枚举所有i,FFT,累加答案即可。
但是,有可能有重复的元素,就将a(i)前面的和它相同的数当成比它大,后面的和它相同的数当成比他小即可。
存疑:FFT的数组到底要开多大啊?四倍?还是只要是一个比卷积结果数组长度大的2的整数幂次就行了?我倾向于后者。求解。
2#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <cstring> #include <vector> using namespace std; #define EPS 1e-8 const double PI = acos(-1.0); struct Complex{ double real,image; Complex(double _real,double _image){ real=_real; image=_image; } Complex(){} }; Complex operator + (const Complex &c1,const Complex &c2){ return Complex(c1.real+c2.real,c1.image+c2.image); } Complex operator - (const Complex &c1,const Complex &c2){ return Complex(c1.real-c2.real,c1.image-c2.image); } Complex operator * (const Complex &c1,const Complex &c2){ return Complex(c1.real*c2.real-c1.image*c2.image,c1.real*c2.image+c1.image*c2.real); } int rev(int id,int len){ int ret=0; for(int i=0;(1<<i)<len;++i){ ret<<=1; if(id&(1<<i)){ ret|=1; } } return ret; } Complex tmp[2100]; //μ±DFT==1ê±ê?DFT, DFT==-1ê±?òê???DFT void IterativeFFT(Complex A[],int len, int DFT){//??3¤?è?alen(2μ??Y)μ?êy×é??DDDFT±??? for(int i=0;i<len;++i){ tmp[rev(i,len)]=A[i]; } for(int i=0;i<len;++i){ A[i]=tmp[i]; } for(int s=1;(1<<s)<=len;++s){ int m=(1<<s); Complex wm=Complex(cos(DFT*2*PI/m),sin(DFT*2*PI/m)); for(int k=0;k<len;k+=m){//?aò?2??áμ?°üo?μ?êy×é?a????êy??ê?(1<<s) Complex w=Complex(1,0); for(int j=0;j<(m>>1);++j){//??°?òyàí£??ù?Yá???×ó?úμ????????úμ? Complex t=w*A[k+j+(m>>1)]; Complex u=A[k+j]; A[k+j]=u+t; A[k+j+(m>>1)]=u-t; w=w*wm; } } } if(DFT==-1){ for(int i=0;i<len;++i){ A[i].real/=len; A[i].image/=len; } } } Complex A[2100],B[2100]; int wq,qw,a[2100],ans[2100][2100],l[2100],r[2100],now,i,j,k,n,m,x; int read() { char c; int ans=0; c=getchar(); while (c<‘0‘ || c>‘9‘) c=getchar(); while (c>=‘0‘ && c<=‘9‘) ans=ans*10+c-48,c=getchar(); return ans; } int main() { wq=read(); for (qw=1;qw<=wq;qw++) { n=read(); m=read(); for (i=1;i<=n;i++) a[i]=read(); memset(ans,0,sizeof(ans)); for (i=1;i<=n;i++) { memset(l,0,sizeof(l)); l[0]=1; memset(r,0,sizeof(r)); r[0]=1; now=0; for (j=i-1;j>=1;j--) { if (a[j]>=a[i]) now++; l[now]++; } int len1=now+1; now=0; for (j=i+1;j<=n;j++) { if (a[j]>a[i]) now++; r[now]++; } int len2=now+1; memset(A,0,sizeof(A)); memset(B,0,sizeof(B)); for(int j=0;j<len1;++j){ A[j]=Complex(l[j],0); } for(int j=0;j<len2;++j){ B[j]=Complex(r[j],0); } int len; for(int j=0;;++j){ if((1<<j)>=len1+len2){ len=(1<<j); break; } } IterativeFFT(A,len,1); IterativeFFT(B,len,1); for(int j=0;j<len;++j){ A[j]=A[j]*B[j]; } IterativeFFT(A,len,-1); for(int j=0;j<len;++j){ ans[a[i]][j]+=(int)(A[j].real+0.5); } } for (i=1;i<=m;i++) { k=read(); x=read(); printf("%d\n",ans[x][k-1]); } } }
【FFT】OpenJ_POJ - C17H - Reverse K-th Problem
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。