题解 城市地平线

传送门

于是,只有我不会 T1 的世界诞生了

一个区间合法的条件是左右端点是区间前 \(k\)
容易做到 \(O(n^2\log n)\),但然后就不会了,甚至在笛卡尔树上折腾了半天下不来
枚举作为 k 大的端点是不便于计算的
那么枚举第 \(k\) 大的位置,则所有比这个数大的位置都是可行的端点
那么若比第 \(i\) 个数大的有 \(x\) 个,这个数是从左到右第 \(rk\)
则贡献为 \(\min(rk, k, x-rk+1, x-k+1)\)(这个数的左右各 k 个)
发现这个东西是关于 \(k\) 的分段函数
将两个系数分别差分维护即可
复杂度 \(O(n\log n)\)

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, l, r;
int h[N];

namespace force{
	int sta[N], top;
	bool calc(int i, int j, int k) {
		top=0;
		for (int l=i; l<=j; ++l) sta[++top]=h[l];
		sort(sta+1, sta+top+1);
		return lower_bound(sta+1, sta+top+1, h[i])-sta>=top-k+1 && lower_bound(sta+1, sta+top+1, h[j])-sta>=top-k+1;
	}
	int solve(int k) {
		// cout<<"solve: "<<k<<endl;
		int ans=0;
		for (int i=1; i<=n; ++i)
			for (int j=i+k-1; j<=n; ++j)
				ans+=calc(i, j, k);
		// cout<<ans<<endl;
		return ans;
	}
	void solve() {
		int ans=0;
		for (int i=l; i<=r; ++i) ans^=solve(i);
		cout<<ans<<endl;
	}
}

namespace task1{
	int ans[N], bit[N], sum;
	inline void add(int i) {for (; i; i-=i&-i) ++bit[i];}
	inline int query(int i) {int ans=0; for (; i<=n; i+=i&-i) ans+=bit[i]; return ans;}
	void solve() {
		for (int i=1; i<=n; ++i) {
			for (int j=1; j<=n; ++j) bit[j]=0;
			for (int j=i; j<=n; ++j) {
				add(h[j]);
				// cout<<"ij: "<<i<<' '<<j<<' '<<max(query(h[i]), query(h[j]))<<endl;
				++ans[max(query(h[i]), query(h[j]))];
				--ans[j-i+2];
			}
		}
		for (int i=1; i<=n; ++i) ans[i]+=ans[i-1];
		// cout<<"ans: "; for (int i=1; i<=n; ++i) cout<<ans[i]<<' '; cout<<endl;
		for (int i=l; i<=r; ++i) sum^=ans[i];
		cout<<sum<<endl;
	}
}

namespace task2{
	int bit[N];
	inline void add(int i) {for (; i; i-=i&-i) ++bit[i];}
	inline void del(int i) {for (; i; i-=i&-i) --bit[i];}
	inline int query(int i) {int ans=0; for (; i<=n; i+=i&-i) ans+=bit[i]; return ans;}
	int solve(int k) {
		int ans=0;
		for (int i=1; i+k-1<=n; ++i) {
			for (int j=i; j<i+k-1; ++j) add(h[j]);
			int j;
			for (j=i+k-1; j<=n; ++j) {
				add(h[j]);
				if (query(h[i])>k) break;
				if (query(h[j])<=k) ++ans;
			}
			while (j>=i) del(h[j--]);
		}
		return ans;
	}
	void solve() {
		int ans=0;
		for (int i=l; i<=r; ++i) ans^=solve(i);
		cout<<ans<<endl;
	}
}

namespace task3{
	int bit[N];
	ll ans[N], sum;
	inline void add(int i) {for (; i; i-=i&-i) ++bit[i];}
	inline int query(int i) {int ans=0; for (; i<=n; i+=i&-i) ans+=bit[i]; return ans;}
	void solve() {
		for (int i=1; i<=n; ++i) {
			add(h[i]);
			int x=n-h[i]+1, rk=query(h[i]), t=min(rk, x-rk+1);
			int pos=(x+1)>>1;
			for (int k=l; k<=r; ++k) ans[k]+=max(0, min(min(rk, k), min(x-rk+1, x-k+1)));
		}
		for (int i=l; i<=r; ++i) sum^=ans[i];
		cout<<sum<<endl;
	}
}

namespace task{
	int bit[N];
	ll ans1[N], ans2[N], ans;
	inline void add(int i) {for (; i; i-=i&-i) ++bit[i];}
	inline int query(int i) {int ans=0; for (; i<=n; i+=i&-i) ans+=bit[i]; return ans;}
	void solve() {
		for (int i=1; i<=n; ++i) {
			add(h[i]);
			int x=n-h[i]+1, rk=query(h[i]), t=min(rk, x-rk+1);
			int pos=(x+1)>>1;
			if (t<=0) continue;
			if (t<pos) {
				++ans1[1], --ans1[t];
				ans2[t]+=t, ans2[x+1-t+1]-=t;
				--ans1[x+1-t+1], ans2[x+1-t+1]+=x+1;
				++ans1[x+1], ans2[x+1]-=x+1;
			}
			else {
				++ans1[1], --ans1[pos+1];
				--ans1[pos+1], ans2[pos+1]+=x+1;
				++ans1[x+1], ans2[x+1]-=x+1;
			}
		}
		for (int i=1; i<=n; ++i) ans1[i]+=ans1[i-1], ans2[i]+=ans2[i-1];
		for (int i=l; i<=r; ++i) ans^=ans1[i]*i+ans2[i];
		cout<<ans<<endl;
	}
}

signed main()
{
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);

	n=read(); l=read(); r=read();
	for (int i=1; i<=n; ++i) h[i]=read();
	// force::solve();
	// if (n<=1000) task1::solve();
	// else task2::solve();
	task::solve();

	return 0;
}
posted @ 2022-04-30 15:44  Administrator-09  阅读(4)  评论(0编辑  收藏  举报