Files
2019-03-15 13:47:54 +04:00

186 lines
4.1 KiB
Java

package chelper;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import java.util.TreeSet;
import io.InputReader;
import io.OutputWriter;
import misc.SimpleSavingChelperSolution;
public class TaskD extends SimpleSavingChelperSolution {
private Comparator<Interval> sortLeft = new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
int t = o1.l.compareTo(o2.l);
if (t != 0) {
return t;
}
return Integer.compare(o1.i, o2.i);
}
};
private Comparator<Interval> sortRight = new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
int t = o1.r.compareTo(o2.r);
if (t != 0) {
return t;
}
return Integer.compare(o1.i, o2.i);
}
};
public void solve(int testNumber, InputReader in, OutputWriter out) {
wrapSolve(testNumber, in, out);
}
class Ratio implements Comparable<Ratio> {
long num, denom;
public Ratio(long num, long denom) {
this.num = num;
this.denom = denom;
}
@Override
public int compareTo(Ratio o) {
long a = num * o.denom;
long b = o.num * denom;
return Long.compare(a, b);
}
}
class Interval {
Ratio l, r;
int i;
int order = -1;
public Interval(Ratio l, Ratio r, int i) {
this.l = l;
this.r = r;
this.i = i;
}
}
long countOneSide(List<Interval> intervals) {
}
@Override
public void solve(int testNumber) {
int n = in.nextInt();
int maxW = in.nextInt();
List<Interval> left = new ArrayList<>();
List<Interval> right = new ArrayList<>();
long res = 0;
for (int i = 0; i < n; i++) {
int x = in.nextInt();
int v = in.nextInt();
// double minTime = Math.abs(x) / (Math.abs(v) + maxW);
// double maxTime = Math.abs(x) / (Math.abs(v) - maxW);
Ratio minTime = new Ratio(Math.abs(x), Math.abs(v) + maxW);
Ratio maxTime = new Ratio(Math.abs(x), Math.abs(v) - maxW);
if (x < 0) {
left.add(new Interval(minTime, maxTime, i));
} else {
right.add(new Interval(minTime, maxTime, i));
}
}
Comparator<Interval> check = new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
int t = o1.l.compareTo(o2.l);
if (t != 0) {
return t;
}
t = o1.r.compareTo(o2.r);
return t;
}
;
};
TreeMap<Interval, Integer> s = new TreeMap<>(check);
for (Interval interval : left) {
s.putIfAbsent(interval, 0);
s.put(interval, s.get(interval) + 1);
}
for (Integer integer : s.values()) {
res += (integer - 1L) * (integer - 0L) / 2;
}
s = new TreeMap<>(check);
for (Interval interval : right) {
s.putIfAbsent(interval, 0);
s.put(interval, s.get(interval) + 1);
}
for (Integer integer : s.values()) {
res += (integer - 1L) * (integer - 0L) / 2;
}
TreeSet<Interval> rightSortLeft = new TreeSet<>(sortLeft);
for (Interval interval : right) {
rightSortLeft.add(new Interval(interval.l, interval.r, interval.i));
}
int howManyLeft = right.size();
for (Interval interval : rightSortLeft) {
interval.order = howManyLeft;
howManyLeft--;
}
TreeSet<Interval> rightSortRight = new TreeSet<>(sortRight);
for (Interval interval : right) {
rightSortRight.add(new Interval(interval.l, interval.r, interval.i));
}
howManyLeft = 0;
for (Interval interval : rightSortRight) {
howManyLeft++;
interval.order = howManyLeft;
}
for (Interval interval : left) {
Interval higher = rightSortLeft.higher(new Interval(interval.r, interval.r, n));
int toRight = 0;
if (higher != null) {
toRight = higher.order;
}
Interval lower = rightSortRight.lower(new Interval(interval.l, interval.l, -1));
int toLeft = 0;
if (lower != null) {
toLeft = lower.order;
}
res += right.size() - toLeft - toRight;
}
out.println(res);
}
}