qwerty787788

Lib

Nov 18th, 2014
580
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.05 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. public class Lib {
  5.     FastScanner in;
  6.     PrintWriter out;
  7.  
  8.     void solve() {
  9.  
  10.     }
  11.  
  12.     class MinCostMaxFlowGraph {
  13.         int n;
  14.         ArrayList<Edge>[] g;
  15.  
  16.         class Edge {
  17.             int from, to;
  18.             long cap, flow, cost;
  19.             Edge rev;
  20.  
  21.             public Edge(int from, int to, long cap, long flow, long cost) {
  22.                 super();
  23.                 this.from = from;
  24.                 this.to = to;
  25.                 this.cap = cap;
  26.                 this.flow = flow;
  27.                 this.cost = cost;
  28.             }
  29.         }
  30.  
  31.         class Vertex implements Comparable<Vertex> {
  32.             int v;
  33.             Edge e;
  34.             long d;
  35.  
  36.             public Vertex(int v) {
  37.                 super();
  38.                 this.v = v;
  39.             }
  40.  
  41.             @Override
  42.             public int compareTo(Vertex o) {
  43.                 return d < o.d ? -1 : d > o.d ? 1 : v - o.v;
  44.             }
  45.  
  46.         }
  47.  
  48.         public MinCostMaxFlowGraph(int n) {
  49.             super();
  50.             this.n = n;
  51.             g = new ArrayList[n];
  52.             for (int i = 0; i < n; i++)
  53.                 g[i] = new ArrayList<Edge>();
  54.         }
  55.  
  56.         public void addEdge(int fr, int to, int cap, long cost) {
  57.             Edge e1 = new Edge(fr, to, cap, 0, cost);
  58.             Edge e2 = new Edge(to, fr, 0, 0, -cost);
  59.             e1.rev = e2;
  60.             e2.rev = e1;
  61.             g[fr].add(e1);
  62.             g[to].add(e2);
  63.         }
  64.  
  65.         public long[] getMinCostMaxFlow(int source, int target) {
  66.             long[] h = new long[n];
  67.             for (boolean changed = true; changed;) {
  68.                 changed = false;
  69.                 for (int i = 0; i < n; i++) {
  70.                     for (Edge e : g[i]) {
  71.                         if (e.cap > 0 && h[e.to] > h[e.from] + e.cost) {
  72.                             h[e.to] = h[e.from] + e.cost;
  73.                             changed = true;
  74.                         }
  75.                     }
  76.                 }
  77.             }
  78.             Vertex[] vertices = new Vertex[n];
  79.             long[] d = new long[n];
  80.             for (int i = 0; i < vertices.length; i++) {
  81.                 vertices[i] = new Vertex(i);
  82.             }
  83.             int flow = 0;
  84.             long cost = 0;
  85.             while (true) {
  86.                 dijkstra(source, vertices, d, h);
  87.                 if (d[target] == Long.MAX_VALUE) {
  88.                     break;
  89.                 }
  90.                 long addFlow = Long.MAX_VALUE;
  91.                 Vertex v = vertices[target];
  92.                 while (v != vertices[source]) {
  93.                     addFlow = Math.min(addFlow, v.e.cap - v.e.flow);
  94.                     v = vertices[v.e.from];
  95.                 }
  96.                 cost += (d[target] + h[target] - h[source]) * addFlow;
  97.                 flow += addFlow;
  98.                 v = vertices[target];
  99.                 while (v != vertices[source]) {
  100.                     v.e.flow += addFlow;
  101.                     v.e.rev.flow -= addFlow;
  102.                     v = vertices[v.e.from];
  103.                 }
  104.                 for (int i = 0; i < n; i++) {
  105.                     h[i] += d[i] == Long.MAX_VALUE ? 0 : d[i];
  106.                 }
  107.             }
  108.             return new long[] { flow, cost };
  109.         }
  110.  
  111.         void dijkstra(int source, Vertex[] vertices, long[] d, long[] h) {
  112.             TreeSet<Vertex> ts = new TreeSet<Vertex>();
  113.             Arrays.fill(d, Long.MAX_VALUE);
  114.             for (int i = 0; i < vertices.length; i++) {
  115.                 vertices[i].d = Long.MAX_VALUE;
  116.             }
  117.             d[source] = 0;
  118.             vertices[source].d = 0;
  119.             ts.add(vertices[source]);
  120.             while (!ts.isEmpty()) {
  121.                 Vertex v = ts.pollFirst();
  122.                 for (Edge e : g[v.v]) {
  123.                     if (e.flow >= e.cap) {
  124.                         continue;
  125.                     }
  126.                     if (d[e.to] == Long.MAX_VALUE
  127.                             || d[e.to] > d[e.from] + e.cost + h[e.from]
  128.                                     - h[e.to]) {
  129.                         if (e.cost + h[e.from] - h[e.to] < 0) {
  130.                             throw new AssertionError();
  131.                         }
  132.                         if (ts.contains(vertices[e.to])) {
  133.                             ts.remove(vertices[e.to]);
  134.                         }
  135.                         d[e.to] = d[e.from] + e.cost + h[e.from] - h[e.to];
  136.                         vertices[e.to].d = d[e.to];
  137.                         vertices[e.to].e = e;
  138.                         ts.add(vertices[e.to]);
  139.                     }
  140.                 }
  141.             }
  142.         }
  143.     }
  144.  
  145.     class Edge {
  146.         int fr, to;
  147.         long flow, cap;
  148.         Edge rev;
  149.  
  150.         Edge(int fr, int to, long cap) {
  151.             this.fr = fr;
  152.             this.to = to;
  153.             this.cap = cap;
  154.         }
  155.     }
  156.  
  157.     class Flow {
  158.         int n;
  159.         ArrayList<Edge>[] g;
  160.  
  161.         Flow(int n) {
  162.             this.n = n;
  163.             g = new ArrayList[n];
  164.             for (int i = 0; i < n; i++) {
  165.                 g[i] = new ArrayList<>();
  166.             }
  167.             q = new int[n];
  168.             h = new int[n];
  169.             cur = new int[n];
  170.         }
  171.  
  172.         void addEdge(int fr, int to, long cap) {
  173.             Edge e1 = new Edge(fr, to, cap);
  174.             Edge e2 = new Edge(to, fr, 0);
  175.             e1.rev = e2;
  176.             e2.rev = e1;
  177.             g[fr].add(e1);
  178.             g[to].add(e2);
  179.         }
  180.  
  181.         int[] h;
  182.         int[] cur;
  183.         int[] q;
  184.  
  185.         boolean bfs() {
  186.             int qIt = 0, qSz = 0;
  187.             q[qSz++] = 0;
  188.             Arrays.fill(h, -1);
  189.             h[0] = 0;
  190.             while (qIt < qSz) {
  191.                 int v = q[qIt++];
  192.                 for (Edge e : g[v]) {
  193.                     if (e.flow == e.cap)
  194.                         continue;
  195.                     if (h[e.to] == -1) {
  196.                         h[e.to] = h[e.fr] + 1;
  197.                         q[qSz++] = e.to;
  198.                     }
  199.                 }
  200.             }
  201.             return h[n - 1] != -1;
  202.         }
  203.  
  204.         long dfs(int v, long flow) {
  205.             if (v == n - 1 || flow == 0)
  206.                 return flow;
  207.             for (; cur[v] < g[v].size(); cur[v]++) {
  208.                 Edge e = g[v].get(cur[v]);
  209.                 if (h[e.to] != h[e.fr] + 1 || e.flow == e.cap)
  210.                     continue;
  211.                 long add = dfs(e.to, Math.min(flow, e.cap - e.flow));
  212.                 if (add == 0)
  213.                     continue;
  214.                 e.flow += add;
  215.                 e.rev.flow -= add;
  216.                 return add;
  217.             }
  218.             return 0;
  219.         }
  220.  
  221.         long flow() {
  222.             long res = 0;
  223.             while (bfs()) {
  224.                 Arrays.fill(cur, 0);
  225.                 while (true) {
  226.                     long add = dfs(0, Long.MAX_VALUE);
  227.                     if (add == 0)
  228.                         break;
  229.                     res += add;
  230.                 }
  231.             }
  232.             return res;
  233.         }
  234.     }
  235.  
  236.     void FFT(double[] re, double[] im, boolean invert) {
  237.         int n = re.length;
  238.         if (im.length != n)
  239.             throw new AssertionError("Sizes of arrays differ");
  240.         if (Integer.bitCount(n) != 1)
  241.             throw new AssertionError("N is not power of 2");
  242.         if (n != 1) {
  243.             int m = n / 2;
  244.             double[] re1 = new double[m];
  245.             double[] im1 = new double[m];
  246.             double[] re2 = new double[m];
  247.             double[] im2 = new double[m];
  248.             for (int i = 0; i < n; i += 2) {
  249.                 re1[i / 2] = re[i];
  250.                 im1[i / 2] = im[i];
  251.                 re2[i / 2] = re[i + 1];
  252.                 im2[i / 2] = im[i + 1];
  253.             }
  254.             FFT(re1, im1, invert);
  255.             FFT(re2, im2, invert);
  256.             double angle = (invert ? -1 : 1) * Math.PI * 2 / n;
  257.             double epsR = Math.cos(angle);
  258.             double epsI = Math.sin(angle);
  259.             double curR = 1;
  260.             double curI = 0;
  261.             for (int i = 0; i < m; i++) {
  262.                 double real = curR * re2[i] - curI * im2[i];
  263.                 double imag = curI * re2[i] + curR * im2[i];
  264.                 re[i] = re1[i] + real;
  265.                 im[i] = im1[i] + imag;
  266.                 real = -real;
  267.                 imag = -imag;
  268.                 re[i + m] = re1[i] + real;
  269.                 im[i + m] = im1[i] + imag;
  270.                 double nR = curR * epsR - curI * epsI;
  271.                 double nI = curR * epsI + curI * epsR;
  272.                 curR = nR;
  273.                 curI = nI;
  274.                 if (invert) {
  275.                     re[i] /= 2.;
  276.                     im[i] /= 2;
  277.                     re[i + m] /= 2;
  278.                     im[i + m] /= 2;
  279.                 }
  280.             }
  281.         }
  282.     }
  283.  
  284.     long[] mul(long[] a, long[] b) {
  285.         int len = Math.max(a.length, b.length) * 2;
  286.         int mLen = 1;
  287.         while (mLen < len)
  288.             mLen *= 2;
  289.         double[] r1 = new double[mLen];
  290.         double[] i1 = new double[mLen];
  291.         for (int i = 0; i < a.length; i++)
  292.             r1[i] = a[i];
  293.         double[] r2 = new double[mLen];
  294.         double[] i2 = new double[mLen];
  295.         for (int i = 0; i < b.length; i++)
  296.             r2[i] = b[i];
  297.         FFT(r1, i1, false);
  298.         FFT(r2, i2, false);
  299.         double[] rNew = new double[mLen];
  300.         double[] iNew = new double[mLen];
  301.         for (int i = 0; i < mLen; i++) {
  302.             rNew[i] = r1[i] * r2[i] - i1[i] * i2[i];
  303.             iNew[i] = r1[i] * i2[i] + r2[i] * i1[i];
  304.         }
  305.         FFT(rNew, iNew, true);
  306.         long[] res = new long[mLen];
  307.         for (int i = 0; i < mLen; i++)
  308.             res[i] = (long) Math.round(rNew[i]);
  309.         return res;
  310.     }
  311.  
  312.     public static void sort(int[] a, int from, int to) {
  313.         int n = to - from;
  314.         int[] temp = new int[n];
  315.         int[] cnt = new int[1 << 16];
  316.         for (int i = to - 1; i >= from; --i) {
  317.             ++cnt[low(a[i])];
  318.         }
  319.         for (int i = 0; i < cnt.length - 1; ++i) {
  320.             cnt[i + 1] += cnt[i];
  321.         }
  322.         for (int i = to - 1; i >= from; --i) {
  323.             temp[--cnt[low(a[i])]] = a[i];
  324.         }
  325.  
  326.         Arrays.fill(cnt, 0);
  327.         for (int i = n - 1; i >= 0; --i) {
  328.             ++cnt[high(temp[i])];
  329.         }
  330.         cnt[0] += from;
  331.         for (int i = 0; i < cnt.length - 1; ++i) {
  332.             cnt[i + 1] += cnt[i];
  333.         }
  334.         for (int i = n - 1; i >= 0; --i) {
  335.             a[--cnt[high(temp[i])]] = temp[i];
  336.         }
  337.     }
  338.  
  339.     private static int high(int a) {
  340.         return (a ^ Integer.MIN_VALUE) >>> 16;
  341.     }
  342.  
  343.     private static int low(int a) {
  344.         return a & 0xFFFF;
  345.     }
  346.  
  347.     final static double eps = 1e-9;
  348.  
  349.     class Point {
  350.         double x, y;
  351.  
  352.         public Point(double x, double y) {
  353.             super();
  354.             this.x = x;
  355.             this.y = y;
  356.         }
  357.  
  358.         double dist(Point an) {
  359.             double dx = an.x - x;
  360.             double dy = an.y - y;
  361.             return Math.sqrt(dx * dx + dy * dy);
  362.         }
  363.     }
  364.  
  365.     class Line {
  366.         double A, B, C;
  367.         boolean normed;
  368.  
  369.         Line(Point p1, Point p2) {
  370.             A = p2.y - p1.y;
  371.             B = p1.x - p2.x;
  372.             C = -A * p1.x - B * p1.y;
  373.         }
  374.  
  375.         void norm() {
  376.             double z = Math.sqrt(A * A + B * B);
  377.             A /= z;
  378.             B /= z;
  379.             C /= z;
  380.             normed = true;
  381.         }
  382.  
  383.         double dist(Point p) {
  384.             if (!normed)
  385.                 norm();
  386.             return Math.abs(A * p.x + B * p.y + C);
  387.         }
  388.  
  389.         Point intersec(Line another) {
  390.             double zn = A * another.B - another.A * B;
  391.             if (Math.abs(zn) <= eps)
  392.                 return null;
  393.             double x = another.C * B - another.B * C;
  394.             double y = another.A * C - another.C * A;
  395.             return new Point(x / zn, y / zn);
  396.         }
  397.     }
  398.  
  399.     boolean insideSorted(double x, double xLeft, double xRight) {
  400.         return x >= xLeft - eps && x <= xRight + eps;
  401.     }
  402.  
  403.     boolean inside(double x, double xLeft, double xRight) {
  404.         return insideSorted(x, Math.min(xLeft, xRight), Math.max(xLeft, xRight));
  405.     }
  406.  
  407.     class Segment {
  408.         Point p1, p2;
  409.         Line l;
  410.  
  411.         public Segment(Point p1, Point p2) {
  412.             this.p1 = p1;
  413.             this.p2 = p2;
  414.             l = new Line(p1, p2);
  415.         }
  416.  
  417.         boolean onSegment(Point p) {
  418.             if (l.dist(p) > eps)
  419.                 return false;
  420.             return inside(p.x, p1.x, p2.x) && inside(p.y, p1.y, p2.y);
  421.         }
  422.  
  423.         boolean isPoint() {
  424.             return p1.dist(p2) <= eps;
  425.         }
  426.     }
  427.  
  428.     class IntersectionObject {
  429.         boolean isPoint;
  430.         Point point;
  431.         Segment segment;
  432.  
  433.         IntersectionObject(Point point) {
  434.             isPoint = true;
  435.             this.point = point;
  436.         }
  437.  
  438.         IntersectionObject(Segment segment) {
  439.             isPoint = false;
  440.             this.segment = segment;
  441.         }
  442.     }
  443.  
  444.     boolean intersectSorted(double xLeft, double xRight, double yLeft,
  445.             double yRight) {
  446.         return Math.max(xLeft, yLeft) - eps <= Math.min(xRight, yRight);
  447.     }
  448.  
  449.     boolean intersect(double xLeft, double xRight, double yLeft, double yRight) {
  450.         return intersectSorted(Math.min(xLeft, xRight),
  451.                 Math.max(xLeft, xRight), Math.min(yLeft, yRight),
  452.                 Math.max(yLeft, yRight));
  453.     }
  454.  
  455.     IntersectionObject intersect(Segment s1, Segment s2) {
  456.         if (!intersect(s1.p1.x, s1.p2.x, s2.p1.x, s2.p2.x)
  457.                 || !intersect(s1.p1.y, s1.p2.y, s2.p1.y, s2.p2.y))
  458.             return null;
  459.         boolean isPoint1 = s1.isPoint();
  460.         boolean isPoint2 = s2.isPoint();
  461.         if (isPoint1 && isPoint2)
  462.             return new IntersectionObject(s1.p1);
  463.         if (isPoint1) {
  464.             if (s2.onSegment(s1.p1))
  465.                 return new IntersectionObject(s1.p1);
  466.             return null;
  467.         }
  468.         if (isPoint2) {
  469.             if (s1.onSegment(s2.p1))
  470.                 return new IntersectionObject(s2.p1);
  471.             return null;
  472.         }
  473.         Point intersecton = s1.l.intersec(s2.l);
  474.         if (intersecton == null) {
  475.             if (Math.abs(s1.l.dist(s2.p1)) > eps
  476.                     || Math.abs(s2.l.dist(s1.p1)) > eps)
  477.                 return null;
  478.             double xLeft1 = Math.min(s1.p1.x, s1.p2.x);
  479.             double xLeft2 = Math.min(s2.p1.x, s2.p2.x);
  480.             double xRight1 = Math.max(s1.p1.x, s1.p2.x);
  481.             double xRight2 = Math.max(s2.p1.x, s2.p2.x);
  482.             double yLeft1 = Math.min(s1.p1.y, s1.p2.y);
  483.             double yLeft2 = Math.min(s2.p1.y, s2.p2.y);
  484.             double yRight1 = Math.max(s1.p1.y, s1.p2.y);
  485.             double yRight2 = Math.max(s2.p1.y, s2.p2.y);
  486.             Point p1 = new Point(Math.max(xLeft1, xLeft2), Math.max(yLeft1,
  487.                     yLeft2));
  488.             Point p2 = new Point(Math.min(xRight1, xRight2), Math.min(yRight1,
  489.                     yRight2));
  490.             if (s1.l.dist(p1) > eps || s1.l.dist(p2) > eps) {
  491.                 p1 = new Point(Math.max(xLeft1, xLeft2), Math.min(yRight1,
  492.                         yRight2));
  493.                 p2 = new Point(Math.min(xRight1, xRight2), Math.max(yLeft1,
  494.                         yLeft2));
  495.             }
  496.             if (p1.dist(p2) <= eps)
  497.                 return new IntersectionObject(p1);
  498.             Segment newSeg = new Segment(p1, p2);
  499.             return new IntersectionObject(newSeg);
  500.         } else {
  501.             if (!s1.onSegment(intersecton) || !s2.onSegment(intersecton))
  502.                 return null;
  503.             return new IntersectionObject(intersecton);
  504.         }
  505.     }
  506.  
  507.     void solve2() {
  508.         Point p1 = new Point(in.nextDouble(), in.nextDouble());
  509.         Point p2 = new Point(in.nextDouble(), in.nextDouble());
  510.         Point p3 = new Point(in.nextDouble(), in.nextDouble());
  511.         Point p4 = new Point(in.nextDouble(), in.nextDouble());
  512.         Segment s1 = new Segment(p1, p2);
  513.         Segment s2 = new Segment(p3, p4);
  514.         IntersectionObject inter = intersect(s1, s2);
  515.         if (inter == null) {
  516.             out.println("Empty");
  517.             return;
  518.         }
  519.         if (inter.isPoint) {
  520.             out.println(inter.point.x + " " + inter.point.y);
  521.             return;
  522.         }
  523.         Point pAns1 = inter.segment.p1;
  524.         Point pAns2 = inter.segment.p2;
  525.         if (pAns2.x < pAns1.x
  526.                 || (Math.abs(pAns1.x - pAns2.x) <= eps && pAns2.y < pAns1.y)) {
  527.             Point tmp = pAns1;
  528.             pAns1 = pAns2;
  529.             pAns2 = tmp;
  530.         }
  531.         out.println(pAns1.x + " " + pAns1.y);
  532.         out.println(pAns2.x + " " + pAns2.y);
  533.     }
  534.  
  535.     void run() {
  536.         try {
  537.             in = new FastScanner(new File("lib.in"));
  538.             out = new PrintWriter(new File("lib.out"));
  539.  
  540.             solve();
  541.  
  542.             out.close();
  543.         } catch (FileNotFoundException e) {
  544.             e.printStackTrace();
  545.         }
  546.     }
  547.  
  548.     void runIO() {
  549.  
  550.         in = new FastScanner(System.in);
  551.         out = new PrintWriter(System.out);
  552.  
  553.         solve();
  554.  
  555.         out.close();
  556.     }
  557.  
  558.     class FastScanner {
  559.         BufferedReader br;
  560.         StringTokenizer st;
  561.  
  562.         public FastScanner(File f) {
  563.             try {
  564.                 br = new BufferedReader(new FileReader(f));
  565.             } catch (FileNotFoundException e) {
  566.                 e.printStackTrace();
  567.             }
  568.         }
  569.  
  570.         public FastScanner(InputStream f) {
  571.             br = new BufferedReader(new InputStreamReader(f));
  572.         }
  573.  
  574.         String next() {
  575.             while (st == null || !st.hasMoreTokens()) {
  576.                 String s = null;
  577.                 try {
  578.                     s = br.readLine();
  579.                 } catch (IOException e) {
  580.                     e.printStackTrace();
  581.                 }
  582.                 if (s == null)
  583.                     return null;
  584.                 st = new StringTokenizer(s);
  585.             }
  586.             return st.nextToken();
  587.         }
  588.  
  589.         boolean hasMoreTokens() {
  590.             while (st == null || !st.hasMoreTokens()) {
  591.                 String s = null;
  592.                 try {
  593.                     s = br.readLine();
  594.                 } catch (IOException e) {
  595.                     e.printStackTrace();
  596.                 }
  597.                 if (s == null)
  598.                     return false;
  599.                 st = new StringTokenizer(s);
  600.             }
  601.             return true;
  602.         }
  603.  
  604.         int nextInt() {
  605.             return Integer.parseInt(next());
  606.         }
  607.  
  608.         long nextLong() {
  609.             return Long.parseLong(next());
  610.         }
  611.  
  612.         double nextDouble() {
  613.             return Double.parseDouble(next());
  614.         }
  615.     }
  616.  
  617.     public static void main(String[] args) {
  618.         new Lib().runIO();
  619.     }
  620. }
Advertisement
Add Comment
Please, Sign In to add comment