题目大意:
比赛已经进行到了第三场,开始有人预测第三场比赛选手们的排名了。怎么预测呢,我们假设存在以下的规律:
如果选手A在前两场比赛的分数都高于B,则第三场比赛选手A的分数不可能低于B。
排名的规则是这样的,总分相同则名次并列。比如说,如果有5个选手的分数为1000,1000,900,900,800,则他们的名次为1,1,3,3,5.
现在我们知道N个选手在前两场比赛的成绩,如果上述规律始终成立,预测每个选手的最高排名和最低排名。
如果选手A在前两场比赛的分数都高于B,则第三场比赛选手A的分数不可能低于B。
排名的规则是这样的,总分相同则名次并列。比如说,如果有5个选手的分数为1000,1000,900,900,800,则他们的名次为1,1,3,3,5.
现在我们知道N个选手在前两场比赛的成绩,如果上述规律始终成立,预测每个选手的最高排名和最低排名。
输入:
第一行一个整数N,表示有N个选手。(N<=500000)
接下来有N行,每行两个整数S1,S2,所有选手每一场考试的分数在0~650之间。表示前两场比赛选手的分数。
接下来有N行,每行两个整数S1,S2,所有选手每一场考试的分数在0~650之间。表示前两场比赛选手的分数。
输出:
对每个选手,给出两个整数,表示他可能的最高排名和可能的最低排名。
样例输入:
5
250 180
250 132
220 123
132 194
220 105
250 180
250 132
220 123
132 194
220 105
样例输出:
1 3
1 3
3 5
1 5
3 5
1 3
3 5
1 5
3 5
分析:
二位区间前后缀和……,思路详见代码。
code:
#include<cstdio>
#define MAXN 500000
#define MAXS 651
using namespace std;
int M[MAXS+5][MAXS+5],fs[MAXN+5],ss[MAXN+5];
int prefixs[MAXS+5][MAXS+5],suffixs[MAXS+5][MAXS+5];
int n;
int main()
{
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d",&fs[i],&ss[i]);
++fs[i],++ss[i];
++M[fs[i]][ss[i]];
}
for(i=1;i<=MAXS;i++)
{
int tmp=0;
for(j=1;j<=MAXS;j++)
{
tmp+=M[i][j];
prefixs[i][j]=prefixs[i-1][j]+tmp;
}
}
for(i=MAXS;i>=1;i--)
{
int tmp=0;
for(j=MAXS;j>=1;j--)
{
tmp+=M[i][j];
suffixs[i][j]=suffixs[i+1][j]+tmp;
}
}
for(i=1;i<=n;i++)
printf("%d %d\n",suffixs[fs[i]+1][ss[i]+1]+1,n-prefixs[fs[i]-1][ss[i]-1]-(fs[i]==MAXS)*M[1][ss[i]]-(ss[i]==MAXS)*M[fs[i]][1]);
}