灵异事件,求助为什么莫队改一下询问排序方式会WA掉
查看原帖
灵异事件,求助为什么莫队改一下询问排序方式会WA掉
145119
WhiteLabs楼主2021/7/5 22:25

rt,本来写了个莫队,结果T了一个点。于是加了个奇偶优化,虽然没TLE了,但居然WA了...本来AC的几个点也WA掉了。

TLE的记录
WA的记录

求助各位。代码:

#include <bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c&15);c=getchar();}
	return x*f;
}
const int MAXN=3e5+7;
int n,m;
long long ANS;
struct ARR{
	int pos;
	long long sum;
	bool operator < (const ARR &a) const{return sum<a.sum;}
}arr[MAXN];
int len,num,L[MAXN],R[MAXN],block[MAXN];
void build(){
	len=sqrt(n);
	num=ceil(n*1.0/len);
	for(int i=1;i<=num;i++){
		L[i]=R[i-1]+1;
		R[i]=i*len;
	}
	R[num]=n;
	for(int i=1;i<=num;i++)
		for(int j=L[i];j<=R[i];j++)
			block[j]=i;
}
struct QUE{
	int l,r,id;
	long long ans;
	bool operator < (const QUE &x) const{return block[l]^block[x.l]?block[l]<block[x.l]:r<x.r;}
}que[MAXN];
bool _cmp(ARR a,ARR b){
	return a.pos<b.pos;
}
bool cmp(QUE a,QUE b){
	return a.id<b.id;
}
int g[MAXN][2];
long long cnt[MAXN];
long long ans;
int l=1,r=0;
void add(int x){
	for(int i=0;i<=1;i++) if(~g[x][i]) if(l<=g[x][i]&&r>=g[x][i]) ans++;//计算x本身对答案的贡献
	for(int i=0;i<=1;i++) if(~g[x][i]) cnt[g[x][i]]++;//先算上位置x对cnt的影响
	ans+=cnt[x];//再加上算了x的所有贡献
}
void del(int x){
	ans-=cnt[x];//先把所有配对数字位于x上的贡献减掉,要先写这个,把x也算上
	for(int i=0;i<=1;i++) if(~g[x][i]) cnt[g[x][i]]--;//再把位置x弄走
	for(int i=0;i<=1;i++) if(~g[x][i]) if(l<=g[x][i]&&r>=g[x][i]) ans--;//计算x本身对答案的贡献
}
void calc(){//把一个数字产生的贡献放到其配对数字上,区间的改变的同时维护这个贡献的正确性,方便统计。
	//也就是说,一个加贡献,另一个数字统计贡献,就能保证当且仅当两个数字都在区间内时会算上。
	for(int i=1;i<=m;i++){
		while(r<que[i].r) add(++r);
		while(r>que[i].r) del(r--);
		while(l>que[i].l) add(--l);
		while(l<que[i].l) del(l++);
		que[i].ans=ans;
	}
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) arr[i].pos=i,arr[i].sum=read();
	sort(arr+1,arr+n+1);
	arr[0].sum=-999999999999999999;
	arr[n+1].sum=999999999999999999;//处理越界问题
	memset(g,-1,sizeof(g));
	for(int i=1;i<=n;i++)
		if((arr[i].sum-arr[i-1].sum)^(arr[i+1].sum-arr[i].sum))
			g[arr[i].pos][0]=arr[i].sum-arr[i-1].sum<arr[i+1].sum-arr[i].sum?arr[i-1].pos:arr[i+1].pos;
		else g[arr[i].pos][0]=arr[i-1].pos,g[arr[i].pos][1]=arr[i+1].pos;
	sort(arr+1,arr+n+1,_cmp);
	for(int i=1;i<=m;i++) que[i].l=read(),que[i].r=read(),que[i].id=i;
//	for(int i=1;i<=n;i++) for(int j=0;j<g[i].size();j++) printf("%d\n",g[i][j]);
	build();
	sort(que+1,que+m+1);
	calc();
	sort(que+1,que+m+1,cmp);
	for(int i=1;i<=m;i++) ANS+=i*que[i].ans;//printf("%lld\n",que[i].ans);
	printf("%lld\n",ANS);
	return 0;
}
2021/7/5 22:25
加载中...