TLE 60pts 求卡常,悬关
查看原帖
TLE 60pts 求卡常,悬关
572133
潘德理2010楼主2024/8/17 19:31

思路:

平衡树,遍历整个数组,维护从 11 到 ii(或者从 nn 到 ii)的数从小到大排序,然后维护其差分,维护差分数组中每个值出现了多少次,再维护有多少个数出现在差分数组中。

平衡树用 pb_ds 实现。(本蒟蒻太菜以至于只会这个,不知道会不会变慢?)

提交记录

代码:

#include<ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#include<bits/stdc++.h>
using namespace std;
struct balanced_tree{
	tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> t;
	void cl(){
		t.clear();
	}
	void ins(int x){
		t.insert(x);
	}
	int sz(){
		return t.size();
	}
	int ord(int x){
		return t.order_of_key(x)+1;
	}
	int bk(int x){
		auto it=t.lower_bound(x);
		it--;
		return *it;
	}
	int ne(int x){
		auto it=t.upper_bound(x);
		return *it;
	}
}t;
inline int read(){
	int re=0;
	char ch=getchar();
	while(ch>='0'&&ch<='9') re=(re*10)+ch-48,ch=getchar();
	return re;
}
int q,n,a[1000100],ans,cnt;
bool r[1000100];
map<int,int> m;
int main(){
	q=read();
	while(q--){
		n=read();
		ans=cnt=0;
		for(int i=1;i<=n;i++){
			a[i]=read();
			t.ins(a[i]);
			int v=t.ord(a[i]);
			if(i==1){
				r[i]=1;
				continue;
			}
			if(v==1){
				int u=t.ne(a[i]);
				if(m[u-a[i]]++==0) cnt++;
			}
			else if(v==t.sz()){
				int u=t.bk(a[i]);
				if(m[a[i]-u]++==0) cnt++;
			}			
			else{
				int x=t.bk(a[i]),y=t.ne(a[i]);
				if(--m[y-x]==0) cnt--;
				if(m[y-a[i]]++==0) cnt++;
				if(m[a[i]-x]++==0) cnt++;
			}
			if(cnt==1) r[i]=1;
		}
		m.clear();
		t.cl();
		cnt=0;
		for(int i=n;i>=2;i--){
			t.ins(a[i]);
			int v=t.ord(a[i]);
			if(i==n){
				if(r[i-1]==1) ans++;
				continue;
			}
			if(v==1){
				int u=t.ne(a[i]);
				if(m[u-a[i]]++==0) cnt++;
			}
			else if(v==t.sz()){
				int u=t.bk(a[i]);
				if(m[a[i]-u]++==0) cnt++;
			}			
			else{
				int x=t.bk(a[i]),y=t.ne(a[i]);
				if(--m[y-x]==0) cnt--;
				if(m[y-a[i]]++==0) cnt++;
				if(m[a[i]-x]++==0) cnt++;
			}
			if(cnt==1&&r[i-1]==1) ans++;
		}
		m.clear();
		t.cl();
		for(int i=1;i<=n;i++){
			r[i]=0;
		}
		printf("%d\n",ans);
	}
}
2024/8/17 19:31
加载中...