【USACO 2012 Open】Running Laps(树状数组)

53 奶牛赛跑
  约翰有 N 头奶牛,他为这些奶牛准备了一个周长为 C 的环形跑牛场。所有奶牛从起点同时起跑,
奶牛在比赛中总是以匀速前进的,第 i 头牛的速度为 Vi。只要有一头奶牛跑完 L 圈之后,比赛就立
即结束了。
有时候,跑得快的奶牛可以比跑得慢的奶牛多绕赛场几圈,从而在一些时刻超过慢的奶牛。这就
是最令观众激动的套圈事件了。请问在整个比赛过程中,套圈事件一共会发生多少次呢?
输入格式
• 第一行:三个整数 NL C, 1 N 105 , 1 L 25000 , 1 C 25000
• 第二行到第 N + 1 行:第 i + 1 行有一个整数 Vi, 1 Vi 106
输出格式
• 单个整数:表示整个比赛过程中,套圈的次数之和
样例输入
4 2 100
20
100
70
1
样例输出
4
解释
两头速度快的奶牛会超过两头速度慢的奶牛
各一次

【分析】

  稍微思考一下的题我就不会了么- -

  算出每头牛跑的圈数(double),因为都是匀速,要超过完整的一圈必须圈数完整的多1。

  但是n^2就会很慢。

  可以拆成整数部分和小数部分来做,排个序,整数部分先直接减掉前面的,小数部分求逆序对,然后在ans里面减掉。

  要用long long

代码如下:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<cmath>
 8 using namespace std;
 9 #define Maxn 100010
10 #define LL long long
11 
12 struct node
13 {
14     double a;
15     LL id;
16 }t[Maxn];
17 
18 LL c[Maxn],v[Maxn];
19 
20 LL mymax(LL x,LL y) {return x>y?x:y;}
21 bool cmp(node x,node y) {return x.a<y.a;}
22 bool cmp2(node x,node y) {return x.id<y.id;}
23 
24 LL n;
25 
26 void add(LL x,LL y)
27 {
28     for(LL i=x;i<=n;i+=i&(-i))
29         c[i]+=y;
30 }
31 
32 LL get_ans(LL x)
33 {
34     LL ans=0;
35     for(LL i=x;i>=1;i-=i&(-i))
36         ans+=c[i];
37     return ans;
38 }
39 
40 int main()
41 {
42     LL l,nc;
43     scanf("%lld%lld%lld",&n,&l,&nc);
44     for(LL i=1;i<=n;i++) scanf("%d",&v[i]);
45     sort(v+1,v+1+n);
46     LL sum=0,ans=0;
47     for(LL i=1;i<=n;i++)
48     {
49         t[i].a=(double)(l*1.0*v[i]/v[n]);
50         LL x=(LL)(t[i].a);
51         ans+=(i-1)*x-sum;
52         sum+=x;
53         t[i].a=t[i].a-x;
54         t[i].id=i;
55     }
56     sort(t+1,t+1+n,cmp);
57     LL p=1;
58     double now=t[1].a;
59     t[1].a=1;
60     for(LL i=2;i<=n;i++)
61     {
62         if(t[i].a-now>0.000001) p++,now=t[i].a;
63         t[i].a=p;
64     }
65     sort(t+1,t+1+n,cmp2);
66     memset(c,0,sizeof(c));
67     for(LL i=n;i>=1;i--)
68     {
69         LL x=(LL)(t[i].a);
70         ans-=get_ans(x-1);
71         add(x,1);
72     }
73     printf("%lld
",ans);
74     return 0;
75 }
usaco 2012 open

2016-10-28 08:35:28

原文地址:https://www.cnblogs.com/Konjakmoyu/p/6006399.html