社区讨论
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 条回复,欢迎继续交流。
正在加载回复...