HDU5751Eades
来源:互联网 发布:老站优化关键词 编辑:程序博客网 时间:2024/05/16 00:57
先处理连续一段中最大值出现位置然后用FFT计算出各个最大值出现次数时的线段树 累加答案
#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<complex>#include<algorithm>#include<iostream>#include<queue>#include<vector>using namespace std;#define ll long longchar c;inline void read(int&a){a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}int n,m;int Rev[600000];inline void Bg(int n){ int L=0; while((1<<L)^n)L++; for(int i=0;i<n;i++)Rev[i]=(Rev[i>>1]>>1)|((i&1)<<(L-1));}#define com complex<double>const double pi=acos(-1);com A[600000],B[600000];int S[600000];com C[600000];inline void Rader(com* a,int n){ for(int i=0;i<n;i++)if(Rev[i]>i)swap(a[Rev[i]],a[i]);}/*inline void FFT(com *a,int n,int f){ Rader(a,n); for(int i=1;i<n;i<<=1) { com w0(cos(pi/i),f*sin(pi/i)); for(int j=0;j<n;j+=i<<1) { com w(1,0); for(int k=0;k<i;k++) { com L=a[j+k],R=w*a[j+k+i]; a[j+k]=L+R; a[j+k+i]=L-R; w=w*w0; } } } if(f==-1) for(int i=0;i<n;i++) a[i]/=n;}*/void FFT(com* a,int len,int flag){ Rader(a,len); for(int i=1;i<len;i<<=1) { com W(cos(pi/i),flag*sin(pi/i)); for(int j=0;j<len;j+=i<<1) { com W0(1,0); for(int k=0;k<i;k++) { com x=a[j+k],y=W0*a[j+k+i]; a[j+k]=x+y; a[j+k+i]=x-y; W0*=W; } } } if(flag==-1) for(int i=0;i<len;i++)a[i]/=len;}int Val[60001];int L[60001],R[60001];vector<int> Q[60001];inline bool cmp(int a,int b){return abs(a)<abs(b);}int main(){ int T; read(T); while(T--) { int n; read(n); for(int i=1;i<=n;i++) Q[i].clear(); for(int i=1;i<=n;i++) read(Val[i]),Q[Val[i]].push_back(i); for(int i=1;i<=n;i++) { L[i]=i; while(L[i]>1&&Val[i]>=Val[L[i]-1])L[i]=L[L[i]-1]; Q[Val[i]].push_back(-L[i]+1); } for(int i=n;i;i--) { R[i]=i; while(R[i]<n&&Val[i]>=Val[R[i]+1])R[i]=R[R[i]+1]; Q[Val[i]].push_back(-R[i]-1); } for(int i=1;i<=n;i++)sort(Q[i].begin(),Q[i].end(),cmp); for(int i=1;i<=n;i++) if(!Q[i].empty()) { int l=0,r=l+1; while(l<Q[i].size()) { while(l+1<Q[i].size()&&Q[i][l+1]<=0) l++; if(l+1==Q[i].size())break; r=l+1; while(Q[i][r]>0) r++; int tl=r-l,len=1; while(tl>len)len*=2; len*=2; //if(len<=4)len*=2; //len*=2; for(int j=0;j<len;j++)C[j]=A[j]=0; Bg(len); A[0]=Q[i][l+1]-abs(Q[i][l]-1)+1; for(int j=1;j<tl-1;j++) A[j]=Q[i][l+j+1]-Q[i][l+j]; A[tl-1]=abs(Q[i][r]+1)-Q[i][r-1]+1; for(int j=0;j<tl-1;j++)C[j]=A[tl-1-j-1]; FFT(A,len,1); FFT(C,len,1); for(int j=0;j<len;j++)B[j]=A[j]*C[j]; FFT(B,len,-1); for(int j=0;j<tl-1;j++) { int T=int(B[j+tl-1].real()+0.5); S[j+1]+=T; } l=r+1; } } ll Ans=0; for(int i=1;i<=n;i++) Ans+=i^S[i],S[i]=0; cout<<Ans<<endl; } return 0;}
0 0
- hdu5751Eades
- HDU5751Eades
- FreeMarker_模板引擎_代码自动生成器_源码下载
- POJ 3042 区间DP(费用提前计算相关的DP)
- OpenCV Tutorial: OpenCV介紹
- JspSmartUpload传入数据库出现乱码问题
- 移动端防止被抓包
- HDU5751Eades
- RESTful Web服务
- C语言基础教学——字符串、判断输出(第六课)
- Android异步批量压缩图片
- C# textBox、openFileDialog、saveFileDialog读写文本文档详解
- Java笔记
- SQL常用函数
- java增删该查的源头 ArrayList增删该查的底层实现
- Android前台Service