# | 用 户 名 | 公园 | 计划 | 抽卡 | 总分 |
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了
以此铭记:
在打题之前,我们一定要看清时限
以上