这份代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9,SqrtN = 502;
int n,m;
int a[N];
struct node{
int num,id;
} tmp[N];
bool cmp(node x,node y){
return x.num < y.num;
}
struct block{
int l,r;
} b[SqrtN];
int block_len,block_cnt;
int belong[N];
void build_block(){
block_len = 300;block_cnt = (n + block_len - 1) / block_len;
for(int i = 1;i <= block_cnt;i++){
b[i].l = b[i - 1].r + 1;
b[i].r = b[i].l + block_len - 1;
}
b[block_cnt].r = n;
for(int i = 1;i <= block_cnt;i++)
for(int j = b[i].l;j <= b[i].r;j++)
belong[j] = i;
}
struct BinaryIndexedTree{
int BIT[N];
int lowbit(int x){
return x & (-x);
}
void update(int pos,int v){
for(int i = pos;i <= n;i += lowbit(i))
BIT[i] += v;
}
int query(int pos){
int ret = 0;
for(int i = pos;i;i -= lowbit(i))
ret += BIT[i];
return ret;
}
} bit;
int L[N];//L[i]:[b[belong[i]].l,i]这一段的逆序对数
int R[N];//R[i]:[i,b[belong[i]].r]这一段的逆序对数
int ans[SqrtN][SqrtN];//ans[i][j]:第i到j块之间的逆序对数
int cnt[SqrtN][N]; //cnt[i][j]:前i块中小于等于j的数的个数
int tmp1[SqrtN],top1;
int tmp2[SqrtN],top2;
void init(){
//块内排序
for(int i = 1;i <= block_cnt;i++)
sort(tmp + b[i].l,tmp + b[i].r + 1,cmp);
//预处理L和R
for(int i = 1;i <= block_cnt;i++){
int temp = 0;
for(int j = b[i].l;j <= b[i].r;j++){
bit.update(a[j],1);
temp += bit.query(n) - bit.query(a[j]);
L[j] = temp;
}
for(int j = b[i].l;j <= b[i].r;j++)
bit.update(a[j],-1);
}
for(int i = 1;i <= block_cnt;i++){
int temp = 0;
for(int j = b[i].r;j >= b[i].l;j--){
bit.update(a[j],1);
temp += bit.query(a[j] - 1);
R[j] = temp;
}
for(int j = b[i].l;j <= b[i].r;j++)
bit.update(a[j],-1);
}
//预处理ans
for(int i = 1;i <= block_cnt;i++)
for(int j = i;j <= block_cnt;j++){
if(i == j){
ans[i][j] = L[b[i].r];
continue;
}
int pos1 = b[i].l,pos2 = b[j].l,temp = 0;
while(pos1 <= b[i].r && pos2 <= b[j].r){
if(pos2 > b[j].r || tmp[pos1].num < tmp[pos2].num)
pos1++;
else{
temp += b[i].r - pos1 + 1;
pos2++;
}
}
ans[i][j] = ans[i + 1][j] + ans[i][j - 1] - ans[i + 1][j - 1] + temp;
}
//预处理cnt
for(short i = 1;i <= block_cnt;i++){
for(int j = b[i].l;j <= b[i].r;j++)
cnt[i][a[j]] = 1;
for(int j = 1;j <= n;j++)
cnt[i][j] = cnt[i][j] + cnt[i][j - 1] + cnt[i - 1][j] - cnt[i - 1][j - 1];
}
}
long long query(int l,int r){
int pos_l = belong[l],pos_r = belong[r];
long long ret = 0;
cout << "DEBUG\n";
if(pos_l == pos_r){
ret = L[r] - L[l - 1];
top1 = 0;top2 = 0;
for(int i = b[pos_l].l;i <= b[pos_l].r;i++){
if(tmp[i].id <= l - 1)
tmp1[++top1] = tmp[i].num;
if(l <= tmp[i].id && tmp[i].id <= r)
tmp2[++top2] = tmp[i].num;
}
int pos1 = 1,pos2 = 1,temp = 0;
while(pos1 <= top1 && pos2 <= top2){
if(pos2 > top2 || tmp1[pos1] < tmp2[pos2])
pos1++;
else{
temp += top1 - pos1 + 1;
pos2++;
}
}
ret -= temp;
return ret;
}
cout << "DEBUG0\n";
ret = ans[pos_l + 1][pos_r - 1] + R[l] + L[r];
top1 = 0;top2 = 0;
for(int i = b[pos_l].l;i <= b[pos_l].r;i++)
if(tmp[i].id >= l)
tmp1[++top1] = tmp[i].num;
for(int i = b[pos_r].l;i <= b[pos_r].r;i++)
if(tmp[i].id <= r)
tmp2[++top2] = tmp[i].num;
cout << "DEBUG1\n";
int pos1 = 1,pos2 = 1,temp = 0;
while(pos1 <= top1 && pos2 <= top2){
if(pos2 > top2 || tmp1[pos1] < tmp2[pos2])
pos1++;
else{
temp += top1 - pos1 + 1;
pos2++;
}
}
cout << "DEBUG2\n";
for(int i = l;i <= b[pos_l].r;i++)
ret += cnt[pos_r - 1][a[i] - 1] - cnt[pos_l][a[i] - 1];
cout << "DEBUG3\n";
for(int i = b[pos_r].l;i <= r;i++)
ret += (cnt[pos_r - 1][n] - cnt[pos_l][n]) - (cnt[pos_r - 1][a[i]] - cnt[pos_l][a[i]]);
cout << "DEBUG4\n";
return ret;
}
int main(){
freopen("P5046.in","r",stdin);
freopen("P5046.out","w",stdout);
//ios::sync_with_stdio(false);
//cin.tie(0);cout.tie(0);
cin >> n >> m;
build_block();
for(int i = 1;i <= n;i++){
cin >> a[i];
tmp[i] = (node){a[i],i};
}
init();
long long ans = 0;
int l = 0,r = 0;
while(m--){
cout << "debug0\n";
cout << l << ' ' << r << '\n';
cin >> l >> r;
cout << l << ' ' << r << '\n';
cout << "debug\n";
l ^= ans;r ^= ans;
cout << "debug1\n";
cout << l << ' ' << r << '\n';
ans = query(l,r);
cout << ans << '\n';
cout << "qwq\n";
}
return 0;
}
我通过调试发现 bug 出在 cin >> l >> r
这里,但始终不知道为什么。