https://hihocoder.com/problemset/problem/1513html
小Hi从小的一大兴趣爱好就是学习,可是他发现尽管他认真学习,依旧有学神考的比他好。c++
小Hi在高中期间参加了市里的期末考试,一共五门:语文、数学、英语、物理、化学。学习
成绩出来以后,小Hi发现有些同窗,全部科目都考的比他好,他很烦恼。因此他想知道全部科目都比本身名次靠前的同窗的人数。spa
为了方便,能够认为不存在两我的某一门名次是相同的。code
其余同窗们也想知道有多少人全面碾压了他们,因此你须要对全部人输出答案。htm
解题方法提示blog
做为从没有用过bitset的人来讲以为有必要作一道题试验下。get
看了“解题方法提示”的你相信已经会了。博客
不会能够看一下这我的的博客:http://www.cnblogs.com/hua-dong/p/8196081.html数学
还不会,那你可能和我同样须要思考。
sa[i][j]:i人j科排名。
rk[i][j]:j科i排名的人。
s[i][j]:j科前i排名的人用二进制表示的结果。
那么这样一来若是想求第i我的的总排名,那么就并一下s[sa[i][1~5]-1][1~5]获得的二进制数查一下里面的1有多少个便可。
显然复杂度是O(n^2)的,可是相似压位的想法能够降复杂度,使用c++的bitset能将复杂度变为O(n^2/32)。
#include<stack> #include<queue> #include<cstdio> #include<cstring> #include<bitset> #include<algorithm> using namespace std; inline int read(){ int x=0,w=1;char ch=0; while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*w; } const int N=3e4+5; bitset<N>s[N][6],tmp; int rk[N][6],sa[N][6]; int main(){ int n=read(); for(int i=1;i<=n;i++){ for(int j=1;j<=5;j++){ sa[i][j]=read(); rk[sa[i][j]][j]=i; } } for(int i=1;i<=5;i++){ for(int j=1;j<=n;j++){ s[j][i]=s[j-1][i]; s[j][i].set(rk[j][i]); } } for(int i=1;i<=n;i++){ tmp=s[sa[i][1]-1][1]; for(int j=2;j<=5;j++){ tmp&=s[sa[i][j]-1][j]; } printf("%d\n",(int)tmp.count()); } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文做者:luyouqi233。 +
+欢迎访问个人博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++