[有详细注释]树状数组除Hack全WA(对照题解调试无果)
查看原帖
[有详细注释]树状数组除Hack全WA(对照题解调试无果)
978583
Kayisama楼主2024/1/29 14:33

RT,我已经调试好久了,但还是除Hack以外全WA

求dalao们帮忙看看

/bx/bx/bx

代码:

#include <bits/stdc++.h>
using namespace std;
//if you wanna use pbds,please open \
Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include\c++\x86_64-w64-mingw32\bits\extc++.h
//to find the lib names
//and open the code under this code
//using namespace __gnu_pbds;
//This is a O(1) copy list\
#include <ext/rope>\
using namespace __gnu_cxx;
namespace MySpace{
	#define max(a,b) (([](auto ta,auto tb){return ta>tb?ta:tb;})((a),(b)))
	#define min(a,b) (([](auto ta,auto tb){return ta<tb?ta:tb;})((a),(b)))
	#define lowbit(x) (x&(-x))
	#ifdef ONLINE_JUDGE
	#define getchar getchar_unlocked
	#endif
	template <typename T>
	inline T read(){
		T now=0,nev=1;
		char c=getchar();
		while(c<'0' || c>'9') {
			if(c=='-') nev=-1;
			c=getchar();
		}
		while(c>='0' && c<='9') now=(now<<1)+(now<<3)+(c&15),c=getchar();
		return now*nev;
	}
	template<typename T>
	T qpow(T a,T n,T p){
		T res=1;
		while (n){
			if (n&1) res=1ll*res*a%p;
			a=1ll*a*a%p;
			n>>=1;
		}
		return res;
	}
	template<typename T>
	T gcd(T a,T b){return (b>0?gcd(b,a%b):a);}
}
using namespace MySpace;
//const int INF=0x66CCFF66;
#define int long long
//加入一个好对 
#define pb(a,b) pir.push_back({min(a.pos,b.pos),max(a.pos,b.pos)})
const int maxn=3e5+5;
using ll=long long;
int n,m;
ll ans;
struct aa{
	int pos;//位置 
	ll v;//值 
}a[maxn];
int tr[maxn];//树状数组 
struct dui{//存储好对 
	int l,r;
	bool operator<(const dui tmp) const{//按R排序 
		if (r==tmp.r) return l<tmp.l;
		else r<tmp.r;
	}
};
struct duii{//存储询问 
	int q,l,r;
	bool operator<(const duii tmp) const{//按R排序 
		if (r==tmp.r) return l<tmp.l;
		else r<tmp.r;
	}
};
vector<dui> pir;//存储好对 
vector<duii> que;//存储询问 
void update(int x){//树状数组更新 
	while (x<=n){
		tr[x]++;
		x+=lowbit(x);
	}
	return;
}
int query(int x){//树状数组查询 
	int res=0;
	while (x){
		res+=tr[x];
		x-=lowbit(x);
	}
	return res;
}
void findGGPair(){//寻找好对 
	pb(a[1],a[2]);//加入前面 
	pb(a[n],a[n-1]);//加入后面 
	for (int i=2;i<n;i++){//遍历中间 
		//   后面的差              前面的差 
		int cz=a[i+1].v-a[i].v,cy=a[i].v-a[i-1].v; 
		if (cz==cy){//相等就都加入 
			pb(a[i+1],a[i]);
			pb(a[i-1],a[i]);
		}else if (cz>cy){//如果后面的差大就加入前面那个 
			pb(a[i-1],a[i]);
		}else{
			pb(a[i+1],a[i]);//不然加入后面那个 
		}
	}
	return;
}
void sumAns(){//计算答案 
	//  指针   结尾 
	int ptr=0,End=pir.size();
	for (auto i:que){//遍历每一个询问 
		int l=i.l,r=i.r,id=i.q;//为了方便进行赋值 
		//putchar('a');
		//没走到头并且目前的好对的r<=询问的r,就把ptr加入到树状数组里 
		while (ptr<End && pir[ptr].r<=r) update(pir[ptr++].l);
		//答案增加 询问数*在区间内的好对的个数 
		ans+=1ll*id*(ptr-query(l-1));
	}
	return;
}
signed main(){
	n=read<int>(),m=read<int>();//读入 
	if (n==1) return printf("0"),0;//特判 
	for (int i=1;i<=n;i++){//记录值和位置 
		a[i].v=read<ll>();
		a[i].pos=i;
	}
	//对a按值升序排序 
	stable_sort(a+1,a+1+n,[](aa aaa,aa baa){
		return aaa.v<baa.v;
	});
	findGGPair();//求好对 
	for (int i=1;i<=m;i++){//读入询问 
		int l=read<int>(),r=read<int>();
		que.push_back({i,l,r});//放入询问 
	}
	stable_sort(pir.begin(),pir.end());//对好对排序 
	stable_sort(que.begin(),que.end());//对询问排序 
	sumAns();//计算答案 
	printf("%lld",ans);//输出 
	return 0;
}




2024/1/29 14:33
加载中...