刚学卡常1s,求助卡常最后100ms
查看原帖
刚学卡常1s,求助卡常最后100ms
100325
peterwuyihong楼主2021/10/4 15:46

有什么不用指令集,光凭大力卡常过去的方法?

注意:写的是pre,nxt比较莫队,不是naive莫队

#include<cmath>
#include<cstdio>
#include<cstring>
#include<cassert>
#include<algorithm>
char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int rd() {
	int x=0;register char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
	return x;
}
inline void print(int x) {
  if(x>9) print(x/10);
  *O++=x%10+'0';
}
#define maxn 2000010
int n,m,c;
int a[maxn],pre[maxn],nxt[maxn],app[maxn];
int pos[maxn],blo;
struct prpr{
	int l,r,id;
	inline bool operator<(const prpr&x)const{
		if(pos[l]^pos[x.l])return l<x.l;
		if(pos[l]&1)return r<x.r;
		return r>x.r;
	}
}q[maxn];
int ans[maxn],res;
int ppre[maxn],nnxt[maxn];
int M;
signed main(){
//	freopen("testdata.in","r",stdin);
	n=rd(),c=rd(),M=rd();
	for(register int i=1;i<=n;i++)a[i]=rd();
	int i;
	for(i=1;i+8<n;i+=8){
		pre[i]=app[a[i]],app[a[i]]=i;
		pre[i+1]=app[a[i+1]],app[a[i+1]]=i+1;
		pre[i+2]=app[a[i+2]],app[a[i+2]]=i+2;
		pre[i+3]=app[a[i+3]],app[a[i+3]]=i+3;
		pre[i+4]=app[a[i+4]],app[a[i+4]]=i+4;
		pre[i+5]=app[a[i+5]],app[a[i+5]]=i+5;
		pre[i+6]=app[a[i+6]],app[a[i+6]]=i+6;
		pre[i+7]=app[a[i+7]],app[a[i+7]]=i+7;
	}while(i<=n)pre[i]=app[a[i]],app[a[i]]=i,i++;
	memset(app,0,sizeof app);
	for(register int i=n;i;i--)nxt[i]=app[a[i]],app[a[i]]=i;
	for(register int i=1;i<=n+1;i++)if(nxt[i]==0)nxt[i]=n+1;
	for(register int i=1;i<=n;i++)ppre[i]=pre[pre[i]],nnxt[i]=nxt[nxt[i]];
	blo=sqrt(n)*1.384;
	for(register int i=1;i<=n;i++)pos[i]=(i-1)/blo+1;
	for(int i=1,l,r;i<=M;i++){
		l=rd(),r=rd();
		if(r-l<=256){
			int j=l+1;
			for(;j+8<r;j+=8){
				ans[i]+=ppre[j]<l&&pre[j]>=l;
				ans[i]+=ppre[j+1]<l&&pre[j+1]>=l;
				ans[i]+=ppre[j+2]<l&&pre[j+2]>=l;
				ans[i]+=ppre[j+3]<l&&pre[j+3]>=l;
				ans[i]+=ppre[j+4]<l&&pre[j+4]>=l;
				ans[i]+=ppre[j+5]<l&&pre[j+5]>=l;
				ans[i]+=ppre[j+6]<l&&pre[j+6]>=l;
				ans[i]+=ppre[j+7]<l&&pre[j+7]>=l;
			}while(j<=r)ans[i]+=ppre[j]<l&&pre[j]>=l,j++;
		}else q[++m]=(prpr){l,r,i};
	}
	std::sort(q+1,q+m+1);
	int l=1,r=0;
	for(register int i=1;i<=m;i++){
		if(r<q[i].r){
			while(r+7<q[i].r){
				res+=ppre[r+1]<l&&pre[r+1]>=l;res+=ppre[r+2]<l&&pre[r+2]>=l;
				res+=ppre[r+3]<l&&pre[r+3]>=l;res+=ppre[r+4]<l&&pre[r+4]>=l;
				res+=ppre[r+5]<l&&pre[r+5]>=l;res+=ppre[r+6]<l&&pre[r+6]>=l;
				res+=ppre[r+7]<l&&pre[r+7]>=l;res+=ppre[r+8]<l&&pre[r+8]>=l;r+=8;
			}
			switch((q[i].r-r)&7){
			case 7:res+=ppre[r+7]<l&&pre[r+7]>=l;case 6:res+=ppre[r+6]<l&&pre[r+6]>=l;
			case 5:res+=ppre[r+5]<l&&pre[r+5]>=l;case 4:res+=ppre[r+4]<l&&pre[r+4]>=l;
			case 3:res+=ppre[r+3]<l&&pre[r+3]>=l;case 2:res+=ppre[r+2]<l&&pre[r+2]>=l;
			case 1:res+=ppre[r+1]<l&&pre[r+1]>=l;}r=q[i].r;
		}
		if(l>q[i].l){
			while(l-7>q[i].l){
				res+=nnxt[l-1]>r&&nxt[l-1]<=r;res+=nnxt[l-2]>r&&nxt[l-2]<=r;
				res+=nnxt[l-3]>r&&nxt[l-3]<=r;res+=nnxt[l-4]>r&&nxt[l-4]<=r;
				res+=nnxt[l-5]>r&&nxt[l-5]<=r;res+=nnxt[l-6]>r&&nxt[l-6]<=r;
				res+=nnxt[l-7]>r&&nxt[l-7]<=r;res+=nnxt[l-8]>r&&nxt[l-8]<=r;l-=8;
			}
			switch((l-q[i].l)&7){
			case 7:res+=nnxt[l-7]>r&&nxt[l-7]<=r;case 6:res+=nnxt[l-6]>r&&nxt[l-6]<=r;
			case 5:res+=nnxt[l-5]>r&&nxt[l-5]<=r;case 4:res+=nnxt[l-4]>r&&nxt[l-4]<=r;
			case 3:res+=nnxt[l-3]>r&&nxt[l-3]<=r;case 2:res+=nnxt[l-2]>r&&nxt[l-2]<=r;
			case 1:res+=nnxt[l-1]>r&&nxt[l-1]<=r;}l=q[i].l;
		}
		if(l<q[i].l){
			while(l+7<q[i].l){
				res-=nnxt[l]>r&&nxt[l]<=r;res-=nnxt[l+1]>r&&nxt[l+1]<=r;
				res-=nnxt[l+2]>r&&nxt[l+2]<=r;res-=nnxt[l+3]>r&&nxt[l+3]<=r;
				res-=nnxt[l+4]>r&&nxt[l+4]<=r;res-=nnxt[l+5]>r&&nxt[l+5]<=r;
				res-=nnxt[l+6]>r&&nxt[l+6]<=r;res-=nnxt[l+7]>r&&nxt[l+7]<=r;l+=8;
			}
			switch((q[i].l-l)&7){
			case 7:res-=nnxt[l+6]>r&&nxt[l+6]<=r;case 6:res-=nnxt[l+5]>r&&nxt[l+5]<=r;
			case 5:res-=nnxt[l+4]>r&&nxt[l+4]<=r;case 4:res-=nnxt[l+3]>r&&nxt[l+3]<=r;
			case 3:res-=nnxt[l+2]>r&&nxt[l+2]<=r;case 2:res-=nnxt[l+1]>r&&nxt[l+1]<=r;
			case 1:res-=nnxt[l+0]>r&&nxt[l+0]<=r;}l=q[i].l;
		}
		if(r>q[i].r){
			while(r-7>q[i].r){
				res-=ppre[r]<l&&pre[r]>=l;res-=ppre[r-1]<l&&pre[r-1]>=l;
				res-=ppre[r-2]<l&&pre[r-2]>=l;res-=ppre[r-3]<l&&pre[r-3]>=l;
				res-=ppre[r-4]<l&&pre[r-4]>=l;res-=ppre[r-5]<l&&pre[r-5]>=l;
				res-=ppre[r-6]<l&&pre[r-6]>=l;res-=ppre[r-7]<l&&pre[r-7]>=l;r-=8;
			}while(r>q[i].r)res-=ppre[r]<l&&pre[r]>=l,r--;
			switch((r-q[i].r)&7){
			case 7:res-=ppre[r-8]<l&&pre[r-8]>=l;case 6:res-=ppre[r-7]<l&&pre[r-7]>=l;
			case 5:res-=ppre[r-6]<l&&pre[r-6]>=l;case 4:res-=ppre[r-5]<l&&pre[r-5]>=l;
			case 3:res-=ppre[r-4]<l&&pre[r-4]>=l;case 2:res-=ppre[r-3]<l&&pre[r-3]>=l;
			case 1:res-=ppre[r-2]<l&&pre[r-2]>=l;}r=q[i].r;
		}
		ans[q[i].id]=res;
	}
	for(register int i=1;i<=M;i++)print(ans[i]),*O++='\n';
fwrite(obuf,O-obuf,1,stdout);
}
2021/10/4 15:46
加载中...