我喜欢由乃,我喜欢lxl。
#include <bits/stdc++.h>
using namespace std;
inline int read() {
int q(0);
char ch(getchar());
while (ch < 48)
ch = getchar();
while (ch > 47)
q = (q << 1) + (q << 3) + (ch ^ 48), ch = getchar();
return q;
}
const int B = 300;
int n, kuai, m, il[100005], ir[100005], id[100005], a[100005], b[100005];
long long z[670][670], t[570][100005], ku[670];
//ku 第i块的区间逆序对数 z 整块i-j的逆序对数 t 第i块j-n的个数
int c[100005];
long long qk[670][670], hk[670][670];
int pai[670][670];//排序
//qk 第i块l-j个 hk 第i块j-r个 pq 第i块前个排序 ph 后个排序
void add(int x, int y) {
if (x <= 0)
return;
for (; x <= n; x += x & (-x))
c[x] += y;
}
int ask(int x) {
int ans = 0;
for (; x; x -= x & (-x))
ans += c[x];
return ans;
}
/*
10 2
10 7 8 6 5 1 3 4 9 2
3 10
2 4
*/
void chuku() {
for (int i = 1; i <= kuai; i++) {
for (int j = il[i]; j <= ir[i]; j++) {
ku[i] += (j - il[i]) - ask(a[j]);
add(a[j], 1);
t[i][a[j]]++;
qk[i][j - il[i] + 1] = ku[i];
}
memset(c, 0, sizeof(c));
}
for (int i = 1; i <= kuai; i++)
for (int j = n; j >= 1; j--)
t[i][j] += t[i][j + 1];
for (int i = 1; i <= kuai; i++) {
long long now = 0;
for (int j = ir[i]; j >= il[i]; j--) {
now += ask(a[j] - 1);
add(a[j], 1);
hk[i][ir[i] - j + 1] = now;
}
//cout << now << endl;
memset(c, 0, sizeof(c));
}
}
void chuz() {
for (int i = 1; i <= kuai; i++) {
z[i][i] = ku[i];
for (int j = i + 1; j <= kuai; j++) {
z[i][j] = z[i][j - 1] + ku[j];
for (int k = il[j]; k <= ir[j]; k++)
z[i][j] += t[j - 1][a[k] + 1] - t[i - 1][a[k] + 1];
}
}
}
void chupai() {
for (int i = 1; i <= kuai; i++) {
sort(b + il[i], b + ir[i] + 1);
for (int j = il[i]; j <= ir[i]; j++)
pai[i][j - il[i] + 1] = b[j];
}
}
void chuqt() {
for (int i = 1; i <= kuai; i++)
for (int j = 1; j <= n; j++)
t[i][j] += t[i - 1][j];
}
int g1[670], g2[670];
int ct[100005];
int gai1(int l, int r) { //l到ir[idl]
int idl = id[l];
for (int i = l; i <= r; i++)
ct[a[i]]++;
int cnt = 0;
for (int i = 1; i <= ir[idl] - il[idl] + 1; i++) {
while (ct[pai[idl][i]]) {
ct[pai[idl][i]]--;
g1[++cnt] = pai[idl][i];
}
if (cnt == r - l + 1)
break;
}
return cnt;
}
int gai2(int l, int r) { //il[idr]到r
int idr = id[r];
for (int i = l; i <= r; i++)
ct[a[i]]++;
int cnt = 0;
for (int i = 1; i <= ir[idr] - il[idr] + 1; i++) {
while (ct[pai[idr][i]]) {
ct[pai[idr][i]]--;
g2[++cnt] = pai[idr][i];
}
if (cnt == r - l + 1)
break;
}
return cnt;
}
int gui(int l1, int l2) {
int j = 0;
long long ans = 0;
for (int i = 1; i <= l1; i++) {
while (j + 1 <= l2 && g2[j + 1] < g1[i])
j++;
ans += j;
}
return ans;
}
/*
10 2
10 7 8 6 5 1 3 4 9 2
3 10
2 4
*/
long long ask(int l, int r) {
if (l > r)
return 0;
int idl = id[l], idr = id[r];
if (idl == idr) {
long long ans = qk[idl][l - il[idl]] + hk[idl][ir[idr] - r];
int l1 = gai1(il[idl], l - 1), l2 = gai2(l, ir[idl]);
/* cout << ans << "ans" << endl;
for (int i = 1; i <= l1; i++)
cout << g1[i] << " ";
cout << endl;
for (int i = 1; i <= l2; i++)
cout << g2[i] << " ";
cout << endl;*/
ans += gui(l1, l2);
l1 = gai1(l, r), l2 = gai2(r + 1, ir[idl]);
ans += gui(l1, l2);
//cout << ans << "ans" << endl << ku[idl] << endl;
return ku[idl] - ans;
}
long long ans = z[idl + 1][idr - 1] + hk[idl][ir[idl] - l + 1] + qk[idr][r - il[idr] + 1];
// cout << idl << " " << idr << endl;
// cout << ans << endl;
for (int i = l; i <= ir[idl]; i++)
ans += max(0LL, (ir[idr - 1] - il[idl + 1] + 1LL)) - (t[idr - 1][a[i]] - t[idl][a[i]]);
// cout << ans << endl;
for (int i = il[idr]; i <= r; i++)
ans += (t[idr - 1][a[i] + 1] - t[idl][a[i] + 1]);
// cout << ans << endl;
int l1 = gai1(l, ir[idl]), l2 = gai2(il[idr], r);
ans += gui(l1, l2);
return ans;
}
signed main() {
n = read(), m = read();
for (int i = 1; i <= n; i++)
a[i] = read(), b[i] = a[i];
kuai = n / B;
if (n % B)
kuai++;
for (int i = 1; i <= kuai; i++) {
il[i] = (i - 1) * B + 1, ir[i] = min(n, i * B);
for (int j = il[i]; j <= ir[i]; j++)
id[j] = i;
}
chuku(), chuqt(), chuz(), chupai();
long long la = 0, ll = 0, rr = 0;
while (m--) {
long long l, r;
l = read(), r = read();
l ^= la, r ^= la;
ll = l, rr = r;
la = ask(l, r);
cout << la << "\n";
}
}
由乃我谢谢你啊,后面忘了。
求助卡常,谢谢