答辩会滚莫队 95pts 求卡常
查看原帖
答辩会滚莫队 95pts 求卡常
371968
ningago寄寄人楼主2023/8/8 21:44

#17 TLE

代码是大常熟答辩。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctype.h>
#include <cmath>

char ST;
//#define int long long
#define ll long long
int read()
{
	int x = 0, f = 1;
	char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	for(;  isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
	return x * f;
}

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define gline debug("now is #%d\n", __LINE__)
#define pii std::pair <int, int>
#define mkp std::make_pair

void ckmax(int &x, int y) { x = x > y ? x : y; }
void ckmin(int &x, int y) { x = x < y ? x : y; }
//#define mod 998244353
//#define mod 1000000007
//void plus_(int &x, int y) { x = (x + y) % mod; }
//void mul_(int &x, int y) { x = 1ll * x * y % mod; }
//int ksm(int a, int b)
//{
//	int res = 1;
//	for(; b; b >>= 1, mul_(a, a))
//		if(b & 1)
//			mul_(res, a);
//	return res;
//}

#define N 500010

int n, m;
int a[N];
struct Query
{
	int l, r, id;
}q[N];
int len, belong[N], L[N], id[N];
bool vis[N];
int pre[N], suc[N];
ll ans[N];

struct node
{
	int id, pre, suc;
}sta[N];
int top;
bool apr[N];

inline int aBs(int x) { return x > 0 ? x : -x; }

char ED;
signed main()
{
	n = read(), m = read();
	for(int i = 1; i <= n; i++) id[a[i] = read()] = i;
	for(int i = 1; i <= m; i++) q[q[i].id = i].l = read(), q[i].r = read();
	len = n / sqrt(m);
	for(int i = 1; i <= n; i++)
		belong[i] = (i - 1) / len + 1;
	for(int i = 1; i <= belong[n]; i++)
		L[i] = (i - 1) * len + 1;
	std::sort(q + 1, q + 1 + m, [&](Query A, Query B) -> bool
	{ return belong[A.l] != belong[B.l] ? belong[A.l] < belong[B.l] : A.r > B.r; });
	int l = 1, r = n, las = 0;
	ll now = 0;
	int tmp = 0;
	for(int i = 1; i <= m; i++)
	{
		int ql = q[i].l, qr = q[i].r;
		if(belong[ql] != las)
		{
			las = belong[ql];
			now = 0;
			r = n;
			for(int i = 1; i <= n; i++) pre[i] = suc[i] = vis[i] = 0;
			for(int i = L[las]; i <= n; i++) vis[a[i]] = 1;
			int bg = 1, ed = n;
			while(!vis[bg]) bg++;
			while(!vis[ed]) ed--;
			for(int i = bg, nx; i != ed; i = nx)
			{
				for(nx = i + 1; !vis[nx]; nx++);
				suc[i] = nx;
				pre[nx] = i;
				now += aBs(id[i] - id[nx]);
			}
		}
		tmp = 0;
		while(qr < r)
		{
			int t = a[r--];
			vis[t] = 0;
			if(pre[t]) tmp -= aBs(id[t] - id[pre[t]]), suc[pre[t]] = suc[t];
			if(suc[t]) tmp -= aBs(id[t] - id[suc[t]]), pre[suc[t]] = pre[t];
			if(pre[t] && suc[t]) tmp += aBs(id[pre[t]] - id[suc[t]]);
			if(tmp >= 500000000 || tmp <= -500000000)
				now += tmp, tmp = 0;
		}
		now += tmp, tmp = 0;
		ll now_ = now;
		l = L[las];
		while(l < ql)
		{
			int t = a[l++];
			vis[t] = 0;
			if(pre[t]) tmp -= aBs(id[t] - id[pre[t]]), sta[++top] = (node){pre[t], pre[pre[t]], suc[pre[t]]}, suc[pre[t]] = suc[t];
			if(suc[t]) tmp -= aBs(id[t] - id[suc[t]]), sta[++top] = (node){suc[t], pre[suc[t]], suc[suc[t]]}, pre[suc[t]] = pre[t];
			if(pre[t] && suc[t]) tmp += aBs(id[pre[t]] - id[suc[t]]);
			if(tmp >= 500000000 || tmp <= -500000000)
				now += tmp, tmp = 0;
		}
		now += tmp, tmp = 0;
		ans[q[i].id] = now;
		now = now_;
		while(top)
		{
			int t = sta[top].id;
			pre[t] = sta[top].pre;
			suc[t] = sta[top].suc;
			top--;
		}
	}
	for(int i = 1; i <= m; i++)
		printf("%lld\n", ans[i]);
	return 0;
}
2023/8/8 21:44
加载中...