题目链接:http://hihocoder.com/problemset/problem/1513
思路:本来n^2的的暴力现在可以用bitset接近o(n)来做,这里bitset的主要用途是用排名来递推去求排名在自己前面的,比如某门课排名第二的就把排名第一的那一位置为1:bs[i][j].set(id[i-1][j]),然后计算第三名时把第二名的保存结果赋值给第三名的(此时就保存有第一名的数据),然后继续把第二名的那一位置为1,以此类推,最后把每一门课以后就行了。
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define fuck(x) cout<<"<"<<x<<">"<<endl
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int maxn = 3e4 + 5;
const int mod = 1e9 + 7;
int n;
int Rank[maxn][5],id[maxn][5];
bitset<maxn>bs[maxn][5],ans;
int main() {
while (~scanf ("%d",&n)){
for (int i=1;i<=n;i++){
for (int j=0;j<5;j++){
scanf ("%d",&Rank[i][j]);
id[Rank[i][j]][j]=i;
bs[i][j].reset();
}
}
for (int i=2;i<=n;i++){
for (int j=0;j<5;j++){
bs[i][j]=bs[i-1][j];
bs[i][j].set(id[i-1][j]);
}
}
for (int i=1;i<=n;i++){
ans.set();
for (int j=0;j<5;j++){
ans&=bs[Rank[i][j]][j];
}
printf ("%d\n",ans.count());
}
}
return 0 ;
}