数列分块入门9TLE到爆
  • 板块学术版
  • 楼主zyxawa
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/8/25 20:48
  • 上次更新2023/10/27 13:40:48
查看原帖
数列分块入门9TLE到爆
673294
zyxawa楼主2022/8/25 20:48

谁能帮我看看数列分块入门 9,我的代码,TLE了只有30分

#include<bits/stdc++.h>
using namespace std;
int n,block,t,st[500],ed[500],belong[100001],id[100001],cnt[100001],ago[100001],now[100001],dp[500][500];
vector <int> G[100001];
void turn(){
	sort(ago+1,ago+1+n);
	for(int i=1;i<=n;i++){
		int mid,l=1,r=n;
		while(l<r){
			mid=(l+r)/2;
			if(ago[mid]<now[i]) l=mid+1;
			else r=mid;
		}
		id[l]=now[i];
		now[i]=l;
	}
}
void init(){
	for(int i=1;i<=belong[n];i++){
		memset(cnt,0,sizeof(cnt));
		int num=0,sum=0;
		for(int j=st[i];j<=n;j++){
			cnt[now[j]]++;
			if(sum<=0&&num<=0||sum<cnt[now[j]]||sum==cnt[now[j]]&&num>now[j]){
				num=now[j];
				sum=cnt[num];
			}
			dp[i][belong[j]]=num;
		}
	}
}
int find(int p,int a,int b){
	return upper_bound(G[p].begin(),G[p].end(),b)-lower_bound(G[p].begin(),G[p].end(),a);
}
int query(int L,int R){
	int p=belong[L],q=belong[R],op=0,maxn=0;
	if(p==q){
		for(int i=L;i<=R;i++){
			int aus=find(now[i],L,R);
			if(maxn<=0&&op<=0||maxn<aus||maxn==aus&&now[i]<op){
				op=now[i];
				maxn=aus;
			}
		}
	}
	else{
		op=dp[p+1][q-1];
		maxn=find(op,L,R);
		for(int i=L;i<=ed[p];i++){
			int aus=find(now[i],L,R);
			if(maxn<=0&&op<=0||maxn<aus||maxn==aus&&now[i]<op){
				op=now[i];
				maxn=aus;
			}
		}
		for(int i=st[p];i<=R;i++){
			int aus=find(now[i],L,R);
			if(maxn<=0&&op<=0||maxn<aus||maxn==aus&&now[i]<op){
				op=now[i];
				maxn=aus;
			}
		}
	}
	return op;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&now[i]);
		ago[i]=now[i];
	}
	turn();
	for(int i=1;i<=n;i++) G[now[i]].push_back(i);
	block=sqrt(n);
	t=n/block;
	if(n%block) t++;
	for(int i=1;i<=t;i++){
		st[i]=(i-1)*block+1;
		ed[i]=i*block;
	}
	ed[t]=n;
	for(int i=1;i<=n;i++) belong[i]=(i-1)/block+1;
	init();
	for(int i=1;i<=n;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",id[query(l,r)]);
	}
	return 0;
}
2022/8/25 20:48
加载中...