您的位置:首页 > 其它

VK Cup 2018 Round 2: D. Contact ATC(思维+树状数组)

2018-03-25 17:21 393 查看
E. Contact ATCtime limit per test 1 secondmemory limit per test 256 megabytesinput standard inputoutput standard outputArkady the air traffic controller is now working with n planes in the air. All planes move along a straight coordinate axis with Arkady's station being at point 0 on it. The i-th plane, small enough to be represented by a point, currently has a coordinate of xi and is moving with speed vi. It's guaranteed that xi·vi < 0, i.e., all planes are moving towards the station.Occasionally, the planes are affected by winds. With a wind of speed vwind (not necessarily positive or integral), the speed of the i-th plane becomes vi + vwind.According to weather report, the current wind has a steady speed falling inside the range [ - w, w] (inclusive), but the exact value cannot be measured accurately since this value is rather small — smaller than the absolute value of speed of any plane.Each plane should contact Arkady at the exact moment it passes above his station. And you are to help Arkady count the number of pairs of planes (i, j) (i < j) there are such that there is a possible value of wind speed, under which planes i and j contact Arkady at the same moment. This value needn't be the same across different pairs.The wind speed is the same for all planes. You may assume that the wind has a steady speed and lasts arbitrarily long.InputThe first line contains two integers n and w (1 ≤ n ≤ 100 000, 0 ≤ w < 105) — the number of planes and the maximum wind speed.The i-th of the next n lines contains two integers xi and vi (1 ≤ |xi| ≤ 105, w + 1 ≤ |vi| ≤ 105, xi·vi < 0) — the initial position and speed of the i-th plane.Planes are pairwise distinct, that is, no pair of (i, j) (i < j) exists such that both xi = xj and vi = vj.OutputOutput a single integer — the number of unordered pairs of planes that can contact Arkady at the same moment.Examplesinput
5 1
-3 2
-3 3
-1 2
1 -3
3 -5
output
3
input
6 1
-3 2
-2 2
-1 2
1 -2
2 -2
3 -2
output
9


这题难在卡精度吧。。其实只用排两次序然后一个很简单的树状数组就搞定了

题意:在数轴上有n架飞机,它们的的位置分别是x[i],它们各以v[i]的速度,朝着原点移动(x[i]*v[i]<0),可是按道理这个时候是有风的,风的范围是[-w, w],你不知道风具体多大,只知道无论风多大每架飞机都一定还可以到达原点(也就是不会被吹不动或者 变成反方向),问你有多少架飞机可能在某个情况下同时到达原点
也就是问有多少对点满足方程

的解p∈[-w, w]

对这个方程求导你就会发现关于p的函数是单调的,这就意味着当且仅当p = -w或者p = w时方程f(p)取得极值
这也就意味着:对于飞机A和B,如果在风速为-w时,A先到达原点,而在风速为w时B先到达[b]原点,那么A和B就有可能同时到达原点[/b],这道题就是统计有多少对飞机满足这个要求
具体怎么统计呢?
先按风速为-w时每架飞机到达原点时间排序,再按风速为w时每架飞机到达远点排序,如果A和B满足在这两个序列中偏序不同,就说明他们可以同时到达原点,统计很好办,按照第一个排序序列一个一个的将飞机加入树状数组,然后在第二个排序序列中查询它前面还有多少架飞机没有加入树状数组中就OK了,复杂度O(nlogn)
为什么会卡常数?
因为有可能刚好风速为-w和w时两架飞机在原点相遇,即函数f(p)在极值点时值为0,这个时候它们在某个序列中应该没有顺序可言,而这个时候按顺序统计就有可能出错
解决方法①:很容易想到其实只要将w加上一个很小的值就可以搞定了,我就是这个方法,但是这个值是多少就很难说了,太大了可能本来无法相遇算成相遇,太小了精度有损失,我试了当这个值为0.00001的时候刚好AC
解决方法②:除法计算改成乘法计算,然后排序之前将飞机离散化,这样应该答案一定是对的,但很麻烦就是了

#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define LL long long
typedef struct Res
{
int id;
double x, v;
bool operator < (const Res &b) const
{
if(fabs(x*b.v)<fabs(v*b.x))
return 1;
return 0;
}
}Point;
Point s[100005];
int n, a[100005], b[100005], tre[100005];
int Query(int k)
{
int ans = 0;
while(k)
{
ans += tre[k];
k -= k &-k;
}
return ans;
}
void Update(int k, int val)
{
while(k<=n)
{
tre[k] += val;
k += k&-k;
}
}
int main(void)
{
int i;
LL ans;
double w;
scanf("%d%lf", &n, &w);
w += 1e-6;
for(i=1;i<=n;i++)
{
scanf("%lf%lf", &s[i].x, &s[i].v);
s[i].id = i, s[i].v -= w;
}
sort(s+1, s+n+1);
for(i=1;i<=n;i++)
a[i] = s[i].id;
for(i=1;i<=n;i++)
s[i].v += 2*w;
sort(s+1, s+n+1);
for(i=1;i<=n;i++)
b[s[i].id] = i;
ans = 0;
for(i=1;i<=n;i++)
{
ans += i-1-Query(b[a[i]]);
Update(b[a[i]], 1);
}
printf("%lld\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: