社区讨论

95pts卡常求助,能卡的都试了

P8078[WC2022] 秃子酋长参与者 4已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@lr7tnlm9
此快照首次捕获于
2024/01/10 21:34
2 年前
此快照最后确认于
2024/01/11 13:05
2 年前
查看原帖
RT,有些卡常用了之后反而更慢了,能加速的卡常都用上了
CPP
#include<bits/stdc++.h>
using namespace std;
const int BUFSIZE = 1 << 24;
char ibuf[BUFSIZE], *is = ibuf, *it = ibuf;
inline char getch(){
    if(is == it)
        it = (is = ibuf) + fread(ibuf, 1, BUFSIZE, stdin);
    return is == it ? EOF : *is++;
}
inline int mread(){
    int res = 0, ch = getch();
    while(!(isdigit(ch)) and ch != EOF) ch = getch();
    while(isdigit(ch)) res = res * 10 + (ch ^ 48), ch = getch();
    return res;
}
const int N = 5e5 + 5;
int n = mread(), m = mread(), a[N], la[N], nxt[N], b[N], e[N], now, ch;
long long ans, res[N];
struct Node{
	int l, r, id;
}s[N];
struct Node2{
	int x, ch;
}v[N];
void build(int l, int r){
	for(int i = 1; i <= n; i ++)
	e[i] = 0;
	for(int i = l; i <= r; i ++)
	e[a[i]] = 1;
	int ls = 0;
	ans = 0;
	for(int i = 1; i <= n; i ++){
		if(e[i]){
			la[i] = ls;
			ls = i;
			if(la[i])
			ans += abs(b[i] - b[la[i]]);
		}
	}
	ls = n + 1;
	for(int i = n; i >= 1; i --){
		if(e[i]){
			nxt[i] = ls;
			ls = i;
		}
	}
	return;
}
void huan(){
	while(now){
		auto x = v[now --];
		nxt[la[x.x]] = x.x;
		la[nxt[x.x]] = x.x;
		ans -= x.ch;
	}
	return;
}
void del(int x){
	ch = 0;
	if(la[x])
	ch -= abs(b[x] - b[la[x]]);
	if(nxt[x] <= n)
	ch -= abs(b[x] - b[nxt[x]]);
	if(la[x] && nxt[x] <= n)
	ch += abs(b[nxt[x]] - b[la[x]]);
	v[++ now] = (Node2){x, ch};
	ans += ch;
	nxt[la[x]] = nxt[x];
	la[nxt[x]] = la[x];
	return;
}
void del2(int x){
	ch = 0;
	if(la[x])
	ch -= abs(b[x] - b[la[x]]);
	if(nxt[x] <= n)
	ch -= abs(b[x] - b[nxt[x]]);
	if(la[x] && nxt[x] <= n)
	ch += abs(b[nxt[x]] - b[la[x]]);
	ans += ch;
	nxt[la[x]] = nxt[x];
	la[nxt[x]] = la[x];
	return;
}
signed main(){
	for(int i = 1; i <= n; i ++){
		a[i] = mread();
		b[a[i]] = i;
	}
	for(int i = 1; i <= m; i ++)
	s[i].l = mread(), s[i].r = mread(), s[i].id = i;
	int qn = 1024;
	sort(s + 1, s + 1 + m, [qn](Node a, Node b){
		if((a.l - 1) / qn == (b.l - 1) / qn)
		return a.r > b.r;
		return a.l < b.l;
	});
	int l, r;
	for(int i = 1; i <= m; i ++){
		if(i <= 1 || (s[i].l - 1) / qn != (s[i - 1].l - 1) / qn){
			ans = 0;
			l = (s[i].l - 1) / qn * qn + 1;
			r = n;
			build(l, r);
			now = 0;
		}
		else
		huan();
		l = (s[i].l - 1) / qn * qn + 1;
		while(r > s[i].r){
			del2(a[r]);
			r --;
		}            
		while(l < s[i].l){
			del(a[l]);
			l ++;
		}
		res[s[i].id] = ans;
	}
	for(int i = 1; i <= m; i ++)
	printf("%lld\n", res[i]);
	return 0;
}

回复

6 条回复,欢迎继续交流。

正在加载回复...