LA 4329 Ping pong
来源:互联网 发布:nginx防止ddos攻击 编辑:程序博客网 时间:2024/06/05 15:32
题意:有n个兵乓球选手,每个人都有唯一的一个技能值,每场比赛需要一个裁判,这个裁判的技能值和标号都要在两个选手之间,问能够举办的比赛的种类。
思路:对于第i个人来说,如果可以求出在他左边比他技能值小的数量ai和在他右边比技能值比他小的人得数量bi,那么就可以分别算出左右两边比他技能值大的选手的数量ci和di,则当第i个人当裁判时,就有ai*di+bi*ci种比赛种类。由于技能值的范围比较小,求ai的时候可以从左到右扫描,计算在i前比它小的技能值的数量,计算方法可以使用树状数组求ai的前缀和(也可以用线段树),计算bi与ai同理,从右向左扫描即可。不过事实证明还是树状数组比较快啊,还比较好写。
代码:
树状数组实现:
#include <iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=100000+10;ll C[maxn],ci[maxn],di[maxn],num[maxn];int lowbit(int x){ return x&-x;}ll sum(int x){ ll ret=0; while(x>0) { ret+=C[x]; x-=lowbit(x); } return ret;}void add(int x,int v,ll n){ while(x<=n) { C[x]+=v; x+=lowbit(x); }}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,n; cin>>t; while(t--) { cin>>n; ll res=0; ll maxnum=0; for(int i=1;i<=n;++i) { cin>>num[i]; maxnum=max(maxnum,num[i]); } memset(C,0,sizeof(C)); for(int i=1;i<=n;++i) { add(num[i],1,maxnum); ci[i]=sum(num[i])-1; } memset(C,0,sizeof(C)); for(int i=n;i>=1;--i) { add(num[i],1,maxnum); di[i]=sum(num[i])-1; } for(int i=1;i<=n;++i) { res+=ci[i]*(n-i-di[i])+di[i]*(i-1-ci[i]); } cout<<res<<endl; } return 0;}
线段树实现:
#include <iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int N=100000;const int maxn=(100000+10)<<1;const int maxm=20000+10;int C[maxn<<1],num[maxm],ci[maxm],di[maxm];void PushUp(int rt){ C[rt]=C[rt<<1]+C[rt<<1|1];}void build(int l,int r,int rt){ if(l==r) { C[rt]=0; return; } int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); PushUp(rt);}int Query(int L,int R,int l,int r,int rt){ if(l>=L&&r<=R) { return C[rt]; } int sum=0; int m=(l+r)>>1; if(m>=L) sum+=Query(L,R,l,m,rt<<1); if(m<R) sum+=Query(L,R,m+1,r,rt<<1|1); return sum;}void Update(int p,int l,int r,int rt){ if(l==r) { C[rt]+=1; return; } int m=(l+r)>>1; if(m>=p) Update(p,l,m,rt<<1); else Update(p,m+1,r,rt<<1|1); PushUp(rt);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,n; cin>>t; while(t--) { cin>>n; build(1,N,1); ll res=0; for(int i=1;i<=n;++i) { cin>>num[i]; Update(num[i],1,N,1); //cout<<Query(1,num[i],1,N,1)<<endl; ci[i]=Query(1,num[i],1,N,1)-1; } build(1,N,1); for(int i=n;i>=1;--i) { Update(num[i],1,N,1); di[i]=Query(1,num[i],1,N,1)-1; } for(int i=1;i<=n;++i) { res+=ci[i]*(n-i-di[i])+di[i]*(i-1-ci[i]); } cout<<res<<endl; } return 0;}
- LA 4329 Ping pong
- LA 4329 Ping pong
- LA 4329 - Ping pong
- LA 4329 Ping pong
- LA 4329 Ping pong
- LA 4329(p197)----Ping pong
- LA 4329 Ping pong 树状数组
- LA 4329 Ping pong / 树状数组
- LA 4329 - Ping pong 树状数组
- LA 4329 - Ping pong(树状数组)
- LA 4329 Ping pong [树状数组]
- 【33.20%】【LA 4320】【Ping pong】
- LA - 4329 - Ping pong(树状数组/线段树)
- LA 4329 - Ping pong 树状数组(Fenwick树)
- LA 4329 Ping pong乒乓比赛【树状数组】
- Beijing 2008 树状数组 ,LA 4329 Ping pong
- UVALive 4329 Ping pong
- UVALive 4329 Ping pong
- 孙大午:年轻人不要惜力
- HTML5 基础篇(一)
- VS2010升级VS2012必备(MVC4 WebPage2.0 Razor2.0资料汇集)
- Android - ListActivity 单击事件的响应
- ProtoBuf 常用序列化/反序列化API
- LA 4329 Ping pong
- 袁岳:有关创业的25个问答
- 为什么要使用Hibernate?
- 有关UITableView的contentSize、contentInset和contentOffset
- sql 时间的模糊查询
- 大小端测试函数.
- 苹果联合创始人:写给想用技术改变世界的年轻人
- 普通继电器工作原理
- 位运算符