題意
Sol
五位數點問題,寫個cdq分治套cdq分治套cdq分治套cdq分析就完了 可以用bitset搞
對於每一科開(n)個bitset,其中(b[i])表示的排名為(1 – i)的人是哪些
查詢的時候把每科的bitset &起來就行了
複雜度(kfrac{n^2}{32})
然後可以分塊加速一下
注意這裡在預處理有個關於勢能分析的操作:如果塊內元素較少的話,可以每次跑根號個,然後和前面的|起來,如果元素較多的話直接從1開始跑
複雜度:(kfrac{nsqrt(n)}{32})
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 30001;
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < `0` || c > `9`) {if (c == `-`) f = -1; c = getchar();}
while (c >= `0` && c <= `9`) x = x * 10 + c - `0`, c = getchar();
return x * f;
}
int N, a[5][MAXN], rak[5][MAXN], base = 1;
bitset<MAXN> B[5][175];
main() {
N = read(); base = sqrt(N);
for (int i = 1; i <= N; i++) for (int j = 0; j < 5; j++) a[j][i] = read(), rak[j][a[j][i]] = i;
for (int j = 0; j < 5; j++)
for (int i = 1; i * base <= N; i++)
for(int k = 1; k <= i * base; k++) B[j][i].set(rak[j][k]);
for (int i = 1; i <= N; i++) {
bitset<MAXN> tmp, cal; tmp.set();
for(int j = 0; j < 5; j++) {
cal.reset();
int now = a[j][i] / base;
cal |= B[j][now];
for(int k = now * base + 1; k <= a[j][i]; k++) cal.set(rak[j][k]);
tmp &= cal;
}
printf("%d
", tmp.count() - 1);
}
}