exam9.3

#
  用  户  名  公园 计划 抽卡   总分 
19
859乔屹 100
03:15:05
40
03:14:01
  140
03:15:05

emm

怎么讲

  T2我把自己优化掉了40分

优化前:

#include<iostream>
#include<cstdio> #include<algorithm> #include<cmath> #define cin(a) scanf("%d",&a) using namespace std; const int maxn=1e5+5; int dui[maxn],siz,now,last; int a[maxn]; int m,n,qu; int ri[maxn]; int len[maxn]; int sum[maxn]; long long ans[maxn]; struct node{ int l,r,k; }t[maxn]; __attribute((always_inline))int h233(const node &a,const node &b) {return a.r==b.r?a.l<b.l:a.r<b.r;} int main() { // freopen("ans.in","r",stdin); // freopen("a.out","w",stdout); cin(n),cin(m),cin(qu); for(int q=1;q<=n;q++) cin>>a[q]; for(int q=1;q<=n;q++) { while(siz<m&&now<n) { ++now; if(!dui[a[now]]) ++siz; ++dui[a[now]]; } if(siz>=m) ri[q]=now; else { last=q; break; } dui[a[q]]--; if(!dui[a[q]]) --siz; } /*for(int q=1;q<=last;q++)  cout<<ri[q]<<" ";  cout<<endl;*/ /*for(int q=1;q<=qu;q++)  {  cin(t[q].l),cin(t[q].r),t[q].k=q;  }  sort(t+1,t+qu+1,h233);*/ /*for(int q=1;q<=qu;q++)  cout<<t[q].l<<" "<<t[q].r<<endl;*/ for(int q=1,x,y;q<=qu;q++) { cin(x),cin(y); long long ans=0; for(int w=x;w<=y;w++) { //cout<<w<<" "<<y<<" "<<(ri[w]+y-2*w)*(y-ri[w]+1)/2<<endl; ans+=max(0,(ri[w]+y-2*w)*(y-ri[w]+1)/2); } cout<<ans<<endl; } /*  int tmp=0;  for(int q=1;q<=qu;q++)  {  if(tmp==t[q].r)  ans[t[q].k]=sum[t[q].l];  else  {  //cout<<t[q].l<<" "<<t[q].r<<endl;  sum[t[q].r+1]=0;  for(int w=t[q].r;w>=t[q].l;w--)  sum[w]=sum[w+1]+max(0,(ri[w]+t[q].r-2*w)*(t[q].r-ri[w]+1)/2);  tmp=t[q].r;  ans[t[q].k]=sum[t[q].l];  for(int w=t[q].l;w<=t[q].r;w++)  cout<<sum[w]<<" ";  cout<<endl<<endl;  }  }*/ /*for(int q=1;q<=qu;q++)  cout<<ans[q]<<endl;*/ }

 显然是$\Theta (n+qn)$的

 $n\leq10000$,$q\leq10000$

 时限2s

 可以过的对吧

 然而我忘了时限是2s

 强行玄学优化:

 

#include<iostream>
#include<cstdio> #include<algorithm> #include<cmath> #define cin(a) scanf("%d",&a) using namespace std; const int maxn=1e5+5; int dui[maxn],siz,now,last; int a[maxn]; int m,n,qu; int ri[maxn]; int len[maxn]; int sum[maxn]; long long ans[maxn]; struct node{ int l,r,k; }t[maxn]; __attribute((always_inline))int h233(const node &a,const node &b) {return a.r==b.r?a.l<b.l:a.r<b.r;} int main() { // freopen("ans.in","r",stdin); // freopen("a.out","w",stdout); cin(n),cin(m),cin(qu); for(int q=1;q<=n;q++) cin>>a[q]; for(int q=1;q<=n;q++) { while(siz<m&&now<n) { ++now; if(!dui[a[now]]) ++siz; ++dui[a[now]]; } if(siz>=m) ri[q]=now; else { last=q; break; } dui[a[q]]--; if(!dui[a[q]]) --siz; } /*for(int q=1;q<=last;q++)  cout<<ri[q]<<" ";  cout<<endl;*/ for(int q=1;q<=qu;q++) { cin(t[q].l),cin(t[q].r),t[q].k=q; } sort(t+1,t+qu+1,h233); /*for(int q=1;q<=qu;q++)  cout<<t[q].l<<" "<<t[q].r<<endl;*/ /*for(int q=1,x,y;q<=qu;q++)  {  cin(x),cin(y);  long long ans=0;  for(int w=x;w<=y;w++)  {  //cout<<w<<" "<<y<<" "<<(ri[w]+y-2*w)*(y-ri[w]+1)/2<<endl;  ans+=max(0,(ri[w]+y-2*w)*(y-ri[w]+1)/2);  }  cout<<ans<<endl;  }*/ int tmp=0; for(int q=1;q<=qu;q++) { if(tmp==t[q].r) ans[t[q].k]=sum[t[q].l]; else { //cout<<t[q].l<<" "<<t[q].r<<endl; sum[t[q].r+1]=0; for(int w=t[q].r;w>=t[q].l;w--) sum[w]=sum[w+1]+max(0,(ri[w]+t[q].r-2*w)*(t[q].r-ri[w]+1)/2); tmp=t[q].r; ans[t[q].k]=sum[t[q].l]; /*for(int w=t[q].l;w<=t[q].r;w++)  cout<<sum[w]<<" ";  cout<<endl<<endl;*/ } } for(int q=1;q<=qu;q++) cout<<ans[q]<<endl; } 

 于是WA40了

 以此铭记:

在打题之前,我们一定要看清时限 

 以上

猜你喜欢

转载自www.cnblogs.com/ooovooo/p/11451417.html
9.3