SPOJ RATING

题意: 有N(N≤300000)coder, 每个coder[i]有两个属性A[i] 和 H[i] , 。

当(A[i] ≥ A[j] && H[i] ≥ H[j]) && (A[i] > A[j] || H[i] > H[j]) 时,认为coder[i] 比 coder[j]优秀 ,问每个coder[i]比多少个其他的coder优秀?

我的代码中 X为A   Y为H

先对X进行升序排序,X相同时对Y进行升序排序

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 int c[100005],k,m,lv[300002]={0};
 7 struct coder{
 8     int x,y,id;
 9 }l[300002];
10 int lowbit(int x){return x&(-x);}                           //树状数组模板,直接用
11 int sum(int b){
12     int  sum=0;
13     while(b>0){
14         sum+=c[b];
15         b-=lowbit(b);
16     }
17     return sum;
18 }
19 void add(int x){
20     while(x<=100005){
21         ++c[x];
22         x+=lowbit(x);
23     }
24 }
25 bool cmp(coder a,coder b){
26     return a.x==b.x?a.y<b.y:a.x<b.x;
27 }
28 int main(){
29         scanf("%d",&k);
30         for(int j=1;j<=k;++j){
31             scanf("%d%d",&l[j].x,&l[j].y);
32             l[j].id=j;                                              //记录ID,用于以后的顺序输出
33         }
34         memset(c,0,sizeof(c));
35         sort(l+1,l+k+1,cmp);
36         for(int i=1;i<=k;i++){
37             if(i>1&&l[i-1].x==l[i].x&&l[i-1].y==l[i].y)lv[l[i].id]=lv[l[i-1].id];//当X1=X2&&Y1=Y2时,直接调用else哪里的方法会统计过多
38             else lv[l[i].id]=sum(l[i].y);                                       //由于已将排好序的,而且经过判断,直接调用的时候,X1=X2时,Y2一定大于Y1,所以可以直接统计
39             add(l[i].y);
40         }
41         for(int i=1;i<=k;i++){
42             printf("%d\n",lv[i]);                   //按顺序一行一个输出
43         }
44     return 0;
45 }

SPOJ RATING

时间: 2024-08-30 06:46:53

SPOJ RATING的相关文章

比赛之树状数组题

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 #define F first 7 #define S second 8 #define MP(a,b) make_pair( make_pair(a,b) , -1 ) 9 typedef pair< pair<int,int

用堆操作不断加入点来找到每个点对应所包含的值的个数的理解

首先还是要清楚一下堆操作的代码,毕竟线段树打多了,打堆的时候总会往线段树方向靠近 首先是建堆: D=1;for(;D<maxn+2;D<<=1); 然后给堆赋予值就可以了 查找区间段的和:int query(int s,int t){    int i=D+s-1,j=D+t+1,ans=0;    for(;i^j^1;i>>=1,j>>=1){        if(~i&1) ans+=sum[i^1];        if(j&1) ans+

CSU-ACM暑假集训基础组训练赛(4)解题报告

•Problem A SPOJ SUB_PROB   AC自动机 •题意: 给定一个长为M(M≤100000 )的文本串,和N(N≤1000)个长度不超过2000的模式串,问每个模式串是否在文本串中出现过? •几乎和周一课件上的第一个例题一模一样.. •把文本串丢到AC自动机里面去跑. •注意: •1.可能有两个相同的模式串(略坑吧.) •2.一个模式串可能是另一个模式串的后缀,即如果一个点的fail指针指向的点是一个“危险节点”,那么它本身也是一个“危险节点”. 1 #include <ios

SPOJ 705 Distinct Substrings(后缀数组)

[题目链接] http://www.spoj.com/problems/SUBST1/ [题目大意] 给出一个串,求出不相同的子串的个数. [题解] 对原串做一遍后缀数组,按照后缀的名次进行遍历, 每个后缀对答案的贡献为n-sa[i]+1-h[i], 因为排名相邻的后缀一定是公共前缀最长的, 那么就可以有效地通过LCP去除重复计算的子串. [代码] #include <cstdio> #include <cstring> #include <algorithm> usi

SPOJ 3273

传送门: 这是一道treap的模板题,不要问我为什么一直在写模板题 依旧只放代码 1 //SPOJ 3273 2 //by Cydiater 3 //2016.8.31 4 #include <iostream> 5 #include <cstring> 6 #include <ctime> 7 #include <cmath> 8 #include <cstdlib> 9 #include <string> 10 #include

HDU 4870 Rating(高斯消元)

HDU 4870 Rating 题目链接 题意:一个人注册两个账号,初始rating都是0,他每次拿低分的那个号去打比赛,赢了加50分,输了扣100分,胜率为p,他会打到直到一个号有1000分为止,问比赛场次的期望 思路:f(i, j)表示i >= j,第一个号i分,第二个号j分时候,达到目标的期望,那么可以列出转移为f(i, j) = p f(i', j') + (1 - p) f(i'' + j'') + 1 f(i', j')对应的是赢了加分的状态,f(i'', j'')对应输的扣分的状态

SPOJ CRAN02 - Roommate Agreement

题目链接:http://www.spoj.com/problems/CRAN02/ 题目大意:N个数字组成的序列,和为0的连续子序列的个数.N<1e6 解题思路:计算前缀和,统计每个数字出现的次数,那么对于数字sum[i], 如果存在k个sum[i],则代表有C(k, 2)个序列和为0,而如果sum[i] = 0,则还要累加上对应的k值. 代码: 1 ll n; 2 int a[maxn]; 3 ll sum[maxn]; 4 map<int, int> mmp; 5 6 void so

spoj GCJ1C09C Bribe the Prisoners

题目链接: http://www.spoj.com/problems/GCJ1C09C/ 题意: In a kingdom there are prison cells (numbered 1 to P) built to form a straight line segment. Cells number i and i+1 are adjacent, and prisoners in adjacent cells are called "neighbours." A wall wi

SPOJ QTREE Query on a tree ——树链剖分 线段树

[题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 20005 int T,n,fr[maxn],h[maxn],to[maxn],ne[maxn]