Example #1
0
        public static void TestSkewHeapMergeAndRemove()
        {
            var heap1 = new SkewHeap();

            heap1.Add(1);
            heap1.Add(23);
            heap1.Add(4);
            heap1.Add(28);
            heap1.Add(24);
            heap1.Add(44);
            heap1.Add(63);
            Assert.AreEqual(heap1.Root.Value, 1);

            var heap2 = new SkewHeap();

            heap2.Add(13);
            heap2.Add(99);
            heap2.Add(17);
            heap2.Add(201);
            heap2.Add(49);
            heap2.Add(105);
            heap2.Add(57);
            Assert.AreEqual(heap2.Root.Value, 13);

            var heap = new SkewHeap();

            heap.Root = heap.Merge(heap1.Root, heap2.Root);
            Assert.AreEqual(heap.Root.Value, 1);

            heap.Remove();
            Assert.AreEqual(heap.Root.Value, 4);
        }
Example #2
0
    public void Solve()
    {
        if (N == 1)
        {
            Console.WriteLine(0);
            return;
        }

        for (int i = 0; i < N; i++)
        {
            Array.Sort(XY[i]);
        }
        Array.Sort(XY,
                   (a, b) => {
            if (a[0] == b[0])
            {
                return(a[1].CompareTo(b[1]));
            }
            return(a[0].CompareTo(b[0]));
        });

        var minST = new SegTreeMin[2];
        var maxST = new SegTreeMax[2];

        for (int i = 0; i < 2; i++)
        {
            minST[i] = new SegTreeMin(N);
            maxST[i] = new SegTreeMax(N);
            for (int j = 0; j < N; j++)
            {
                minST[i].Update(j, XY[j][i]);
                maxST[i].Update(j, XY[j][i]);
            }
        }

        var SH = new SkewHeap <Pair>();

        for (int i = 1; i < N; i++)
        {
            SH.Push(new Pair(i, XY[i][1]));
        }

        long ans = (maxST[0].Max - minST[0].Min) * (maxST[1].Max - minST[1].Min);

        while (SH.Count > 0)
        {
            var p   = SH.Top; SH.Pop();
            int idx = p.Pos;
            maxST[0].Update(idx, XY[idx][1]);
            maxST[1].Update(idx, XY[idx][0]);
            minST[0].Update(idx, XY[idx][1]);
            minST[1].Update(idx, XY[idx][0]);

            var v = (maxST[0].Max - minST[0].Min) * (maxST[1].Max - minST[1].Min);
            ans = Math.Min(ans, v);
        }

        Console.WriteLine(ans);
    }
Example #3
0
        //ビームの更新
        private void UpdateBeam(SkewHeap heap, HashSet <long> puzzlesInHeap, Puzzle nextPuzzle, int beamWidth)
        {
            if (heap.Count == beamWidth)
            {
                puzzlesInHeap.Remove(heap.MinValue().boardHash);
                heap.Pop();
            }

            puzzlesInHeap.Add(nextPuzzle.boardHash);
            heap.Push(nextPuzzle);
        }
Example #4
0
    public void Solve()
    {
        long[] max = new long[3 * N];
        var    SH  = new SkewHeap <long>();
        long   tot = 0;

        for (int i = 0; i < N; i++)
        {
            SH.Push(A[i]);
            tot += A[i];
        }
        max[N - 1] = tot;

        for (int i = N; i < 2 * N; i++)
        {
            tot += A[i];
            SH.Push(A[i]);
            var mm = SH.Top; SH.Pop();
            tot   -= mm;
            max[i] = tot;
        }

        long[] min = new long[3 * N];
        SH  = new SkewHeap <long>();
        tot = 0;
        for (int i = 3 * N - 1; i >= 2 * N; i--)
        {
            SH.Push(-A[i]);
            tot += A[i];
        }
        min[2 * N] = tot;
        for (int i = 2 * N - 1; i >= N; i--)
        {
            tot += A[i];
            SH.Push(-A[i]);
            var mm = SH.Top; SH.Pop();
            tot   -= -mm;
            min[i] = tot;
        }

        long ans = long.MinValue;

        for (int i = N - 1; i < 2 * N; i++)
        {
            ans = Math.Max(ans, max[i] - min[i + 1]);
        }

        Console.WriteLine(ans);
    }
Example #5
0
    public void Solve()
    {
        bool[] visit = new bool[N];
        int[]  BN    = new int[N];
        for (int i = 0; i < N; i++)
        {
            BN[i] = -1;
        }
        SkewHeap <Pair> SH = new SkewHeap <Pair>();

        //visit[S] = true;

        SH.Push(new Pair(S, S));
        BN[S] = S;

        while (SH.Count > 0)
        {
            var p = SH.Top; SH.Pop();
            if (visit[p.Pos])
            {
                continue;
            }
            visit[p.Pos] = true;
            BN[p.Pos]    = p.Cost;
//Console.WriteLine("{0} {1}",p.Pos,p.Cost);
            foreach (var nxt in E[p.Pos])
            {
                if (BN[nxt] < p.Cost)
                {
                    BN[nxt] = Math.Min(p.Cost, nxt);
                    SH.Push(new Pair(nxt, BN[nxt]));
                }
            }
        }
//Console.WriteLine(String.Join(" ",BN));
        var sb = new StringBuilder();

        for (int i = 0; i < N; i++)
        {
            if (BN[i] >= i)
            {
                sb.AppendLine((i + 1).ToString());
            }
        }
        Console.Write(sb.ToString());
    }
Example #6
0
    public void Solve()
    {
        int Inf = (int)1e9;

        int[] min = new int[K];
        for (int i = 0; i < K; i++)
        {
            min[i] = Inf;
        }

        var SH = new SkewHeap <Pair>();

        for (int i = 1; i <= 9; i++)
        {
            if (min[i % K] > i)
            {
                min[i % K] = i;
                SH.Push(new Pair(i % K, i));
            }
        }

        bool[] used = new bool[K];
        while (SH.Count > 0)
        {
            var p    = SH.Top; SH.Pop();
            int now  = p.Pos;
            int cost = p.Cost;
            if (used[now])
            {
                continue;
            }
            used[now] = true;
            for (int j = 0; j < 10; j++)
            {
                var nxt = (now * 10 + j) % K;
                if (min[nxt] > cost + j)
                {
                    min[nxt] = cost + j;
                    SH.Push(new Pair(nxt, min[nxt]));
                }
            }
        }

        Console.WriteLine(min[0]);
    }
Example #7
0
 //ビームを更新するか
 private bool IsUpdateBeam(SkewHeap heap, HashSet <long> puzzlesInHeap, Puzzle nextPuzzle, int beamWidth)
 {
     if (nextPuzzle == null)
     {
         return(false);
     }
     if (!puzzlesInHeap.Contains(nextPuzzle.boardHash))
     {
         return(true);
     }
     if (heap.Count < beamWidth)
     {
         return(false);
     }
     if (nextPuzzle.boardHash == heap.MinValue().boardHash)
     {
         return(true);
     }
     return(false);
 }
Example #8
0
        public static void TestSkewHeapCreation()
        {
            var heap1 = new SkewHeap();

            heap1.Add(1);
            heap1.Add(23);
            heap1.Add(4);
            heap1.Add(28);
            heap1.Add(24);
            heap1.Add(44);
            heap1.Add(63);
            Assert.AreEqual(heap1.Root.Value, 1);

            Assert.AreEqual(heap1.Root.LeftChild.Value, 4);
            Assert.AreEqual(heap1.Root.LeftChild.LeftChild.Value, 63);
            Assert.AreEqual(heap1.Root.LeftChild.RightChild.Value, 24);
            Assert.AreEqual(heap1.Root.RightChild.Value, 23);
            Assert.AreEqual(heap1.Root.RightChild.LeftChild.Value, 44);
            Assert.AreEqual(heap1.Root.RightChild.RightChild.Value, 28);
        }
Example #9
0
        //問題を解く
        public void Solve(Puzzle initialPuzzle)
        {
            IsCanceled = false;
            ViewPuzzles.Clear();
            List <SkewHeap> States    = new List <SkewHeap>();
            int             beamWidth = 50;
            int             nowDepth  = 0;
            int             maxDepth  = initialPuzzle.pieces.Count;

            for (int i = 0; i < 100; i++)
            {
                States.Add(new SkewHeap());
            }
            States[0].Push(initialPuzzle);
            ViewPuzzles.Add(initialPuzzle);             //0手目の結果

            //パズルを解く (1手進める) → ビームサーチ
            while (nowDepth < maxDepth)
            {
                HashSet <long> puzzlesInHeap = new HashSet <long>();
                States[nowDepth + 1] = new SkewHeap();

                while (States[nowDepth].Count > 0)
                {
                    Puzzle nowPuzzle = States[nowDepth].Pop().Clone();
                    SetNextStates(nowPuzzle, beamWidth, States[nowDepth + 1], puzzlesInHeap);
                    if (IsCanceled)
                    {
                        return;
                    }
                }
                if (States[nowDepth + 1].Count > 0)
                {
                    ViewPuzzles.Add(States[nowDepth + 1].MaxValue().Clone()); nowDepth++;
                }
                else
                {
                    break;
                }
            }
        }
 /// <summary>
 /// heap同士のマージを行います
 /// 計算量:O(logN)
 /// </summary>
 /// <param name="sh"></param>
 public void Merge(SkewHeap <T> sh)
 {
     root = Merge(root, sh.root); Count += sh.Count;
 }
Example #11
0
        //ビームサーチの次状態更新
        private void SetNextStates(Puzzle puzzle, int beamWidth, SkewHeap heap, HashSet <long> puzzlesInHeap)
        {
            List <Poly> polys = new List <Poly>(puzzle.wakus);

            for (int i = 0; i < puzzle.pieces.Count; i++)
            {
                polys.Add(puzzle.pieces[i]);
            }

            for (int dstPolyId = 0; dstPolyId < polys.Count; dstPolyId++)
            {
                Poly dstPoly = polys[dstPolyId];
                if (!dstPoly.isExist)
                {
                    continue;
                }

                for (int srcPolyId = 0; srcPolyId < puzzle.pieces.Count; srcPolyId++)
                {
                    Poly srcPoly = puzzle.pieces[srcPolyId];
                    if (!srcPoly.isExist)
                    {
                        continue;
                    }
                    if (dstPoly == srcPoly)
                    {
                        continue;
                    }

                    for (int dstPointId = 0; dstPointId < dstPoly.Count; dstPointId++)
                    {
                        for (int srcPointId = 0; srcPointId < srcPoly.Count; srcPointId++)
                        {
                            //配置情報でsrcPolyが与えられている場合
                            if (srcPoly.isPositionDetected)
                            {
                                if (Point.Compare(srcPoly.points[srcPointId], dstPoly.points[dstPointId]) != 0)
                                {
                                    continue;
                                }
                            }

                            for (int option = 0; option < 4; option++)
                            {
                                if (IsCanceled)
                                {
                                    return;
                                }
                                int  direction = option >> 1;                                  // means : option / 2
                                bool turnflag  = (option & 1) == 1;                            // means : (option % 2) == 1

                                //配置情報でsrcPolyが与えられている場合
                                if (srcPoly.isPositionDetected)
                                {
                                    if (turnflag)
                                    {
                                        continue;
                                    }
                                    Point mul = (dstPoly[dstPointId + direction] - dstPoly[dstPointId]) / (srcPoly[srcPointId - direction] - srcPoly[srcPointId]);
                                    if (mul.Re != 1 || mul.Im != 0)
                                    {
                                        continue;
                                    }
                                }

                                int score = getScore(dstPoly, srcPoly, dstPointId, srcPointId, direction, turnflag, heap.Count == beamWidth ? heap.MinValue().boardScore + 1 - puzzle.boardScore : -1);
                                if (score < 0)
                                {
                                    continue;
                                }

                                Puzzle nextPuzzle = GetNextPuzzle(puzzle, dstPolyId, srcPolyId, dstPointId, srcPointId, direction, turnflag, score);
                                if (IsUpdateBeam(heap, puzzlesInHeap, nextPuzzle, beamWidth))
                                {
                                    UpdateBeam(heap, puzzlesInHeap, nextPuzzle, beamWidth);
                                }
                            }
                        }
                    }
                }
            }
        }
Example #12
0
 public void Merge(SkewHeap <T> heap)
 {
     root = Meld(root, heap.root);
 }
Example #13
0
    public void Solve()
    {
        long Inf = (long)1e18;

        long[] ma = new long[N + 1];
        for (int i = 0; i <= N; i++)
        {
            ma[i] = -Inf;
        }
        Pair[] P = new Pair[N];
        for (int i = 0; i < N; i++)
        {
            P[i] = new Pair(i, D[i]);
        }

        Array.Sort(P, (p, q) => - 1 * (p.D.CompareTo(q.D)));
        var SH = new SkewHeap <Pair>();

        int[] cnt = new int[N];
        long  tD  = 0;
        var   h   = new HashSet <int>();

        for (int i = 0; i < K; i++)
        {
            tD += D[P[i].Idx];
            cnt[T[P[i].Idx]]++;
            h.Add(T[P[i].Idx]);
            if (cnt[T[P[i].Idx]] > 1)
            {
                SH.Push(P[i]);
            }
        }

        ma[h.Count] = tD;
        for (int i = K; i < N; i++)
        {
            int nt = T[P[i].Idx];
            if (h.Contains(nt))
            {
                continue;
            }
            if (SH.Count == 0)
            {
                continue;
            }
            h.Add(nt);
            var p = SH.Top; SH.Pop();
            tD         -= p.D;
            tD         += P[i].D;
            ma[h.Count] = Math.Max(tD, ma[h.Count]);
        }

        long ans = -Inf;

        for (int i = 0; i <= N; i++)
        {
            if (ma[i] == -Inf)
            {
                continue;
            }
            ans = Math.Max(ans, (long)i * (long)i + ma[i]);
        }

        Console.WriteLine(ans);
    }
Example #14
0
    public void Solve()
    {
        int NN = N + 2;

        double[][] dist = new double[NN][];
        for (int i = 0; i < NN; i++)
        {
            dist[i] = new double[NN];
        }
        for (int i = 0; i < NN; i++)
        {
            for (int j = i + 1; j < NN; j++)
            {
                if ((X[i] - X[j]) * (X[i] - X[j]) + (Y[i] - Y[j]) * (Y[i] - Y[j]) < (R[i] + R[j]) * (R[i] + R[j]))
                {
                    dist[i][j] = dist[j][i] = 0;
                }
                else
                {
                    dist[i][j] = dist[j][i] = Math.Sqrt((double)((X[i] - X[j]) * (X[i] - X[j]) + (Y[i] - Y[j]) * (Y[i] - Y[j]))) - (double)(R[i] + R[j]);
                }
            }
        }

//for(int i=0;i<NN;i++) Console.WriteLine(String.Join(" ",dist[i]));

        double[] Min = new double[NN];
        for (int i = 1; i < NN; i++)
        {
            Min[i] = 1e15;
        }

        bool[] used    = new bool[NN];
        int    cntused = 0;

        var SH = new SkewHeap <Pair>();

        SH.Push(new Pair(0, 0));

        while (SH.Count > 0)
        {
            var p   = SH.Top; SH.Pop();
            int now = p.Pos;
            if (used[now])
            {
                continue;
            }
            used[now] = true;
            Min[now]  = p.Cost;
            cntused++;
            if (cntused == NN)
            {
                break;
            }
            for (int j = 0; j < NN; j++)
            {
                if (Min[j] > Min[now] + dist[now][j])
                {
                    Min[j] = Min[now] + dist[now][j];
                    SH.Push(new Pair(j, Min[j]));
                }
            }
        }

        Console.WriteLine(Min[NN - 1]);
    }
Example #15
0
        /// <summary>
        /// SubDendriteを距離閾値に従ってMainDendriteに接続
        /// </summary>
        public void ConnectSubDendritesToMainDendrite()
        {
            // nodelist[0]		: main
            // nodelist[1:]     : sub
            List <List <DendriteNode> > nodelist = new List <List <DendriteNode> >();

            //メインクラスタの分岐,端点ノードを取得
            List <DendriteNode> pnode = main_dendrite.GetEdgeNodeAndBranchNodes();

            nodelist.Add(pnode);

            NotMergedSubDendritesIdx = new HashSet <int>();

            for (int i = 0; i < sub_dendrites.Count; i++)
            {
                //サブクラスタの分岐,端点ノードを取得
                List <DendriteNode> node = sub_dendrites[i].GetEdgeNodeAndBranchNodes();

                nodelist.Add(node);
                NotMergedSubDendritesIdx.Add(i);
            }

            var Q = new SkewHeap <NodeRelation>();

            for (int i = 0; i < nodelist[0].Count; i++)
            {
                for (int j = 1; j < nodelist.Count; j++)
                {
                    double normMin = double.MaxValue;
                    int    argMin  = -1;
                    for (int k = 0; k < nodelist[j].Count; k++)
                    {
                        double d = nodelist[0][i].EuclideanDistanceTo(nodelist[j][k]);
                        if (d <= normMin)
                        {
                            normMin = d;
                            argMin  = k;
                        }
                    }

                    if (argMin != -1 && normMin <= param.distanceThreshold)
                    {
                        Q.Push(new NodeRelation(normMin, i, j, argMin));
                    }
                }
            }

            while (true)
            {
                NodeRelation rel = null;
                while (Q.Empty() == false)
                {
                    rel = Q.Pop();
                    if (nodelist[rel.SlaveClusterIdx].Count > 0)
                    {
                        break;
                    }
                }

                if (Q.Empty())
                {
                    break;
                }

                DendriteNode parent = nodelist[0][rel.MasterNodeIdx];
                DendriteNode cand   = nodelist[rel.SlaveClusterIdx][rel.SlaveNodeIdx];

                //連結ノードにお互いを追加
                cand.AddConnectedNode(parent);
                parent.AddConnectedNode(cand);

                int mainNodeSizePrev = nodelist[0].Count;

                //連結したサブノードリストはメインノードリストに吸収
                nodelist[0].AddRange(nodelist[rel.SlaveClusterIdx]);

                //サブを消去
                nodelist[rel.SlaveClusterIdx].Clear();

                // マージされた
                NotMergedSubDendritesIdx.Remove(rel.SlaveClusterIdx - 1);

                // 吸収されたサブノードから、吸収されていないサブノードまでの距離を算出
                for (int i = mainNodeSizePrev; i < nodelist[0].Count; i++)
                {
                    for (int j = 1; j < nodelist.Count; j++)
                    {
                        double normMin = double.MaxValue;
                        int    argMin  = -1;
                        for (int k = 0; k < nodelist[j].Count; k++)
                        {
                            double d = nodelist[0][i].EuclideanDistanceTo(nodelist[j][k]);
                            if (d <= normMin)
                            {
                                normMin = d;
                                argMin  = k;
                            }
                        }

                        if (argMin != -1 && normMin <= param.distanceThreshold)
                        {
                            Q.Push(new NodeRelation(normMin, i, j, argMin));
                        }
                    }
                }
            }

            main_dendrite.ChangeRootNode(main_dendrite.root);
            pnode = main_dendrite.GetEdgeNodes();
            // どうしてFirstでなくてLastなのかよく分からない
            main_dendrite.ChangeRootNode(pnode.Last());
        }
Example #16
0
    public void Solve()
    {
        List <int>[] E = new List <int> [N];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List <int>();
        }
        for (int i = 0; i < M; i++)
        {
            E[U[i]].Add(i);
            E[V[i]].Add(i);
        }

        long Inf = (long)1e18;

        long[][] min = new long[2][];
        for (int i = 0; i < 2; i++)
        {
            min[i] = new long[M];
            for (int j = 0; j < N; j++)
            {
                min[i][j] = Inf;
            }
        }

        int[] strt = new int[] { S, T };
        for (int t = 0; t < 2; t++)
        {
            var    SH   = new SkewHeap <Pair>();
            bool[] used = new bool[N];
            SH.Push(new Pair(strt[t], 0));
            min[t][strt[t]] = 0;
            while (SH.Count > 0)
            {
                var p    = SH.Top; SH.Pop();
                var now  = p.Pos;
                var cost = p.Cost;
                if (used[now])
                {
                    continue;
                }
                used[now]   = true;
                min[t][now] = cost;
                foreach (var ne in E[now])
                {
                    long nc = cost + D[ne];
                    int  nv = U[ne] == now ? V[ne] : U[ne];
                    if (min[t][nv] > nc)
                    {
                        min[t][nv] = nc;
                        SH.Push(new Pair(nv, nc));
                    }
                }
            }
        }

        long[][]      comb    = new long[2][];
        HashSet <int> minedge = new HashSet <int>();

        for (int t = 0; t < 2; t++)
        {
            int         fr = strt[t];
            int         to = strt[t ^ 1];
            List <Pair> L  = new List <Pair>();
            for (int i = 0; i < N; i++)
            {
                L.Add(new Pair(i, min[t][i]));
            }
            L.Sort((p, q) => p.Cost.CompareTo(q.Cost));

            comb[t]     = new long[N];
            comb[t][fr] = 1;
            long dmin = min[t][to];

            foreach (var pp in L)
            {
                int now = pp.Pos;
                if (min[t][now] >= dmin)
                {
                    break;
                }
                foreach (var ne in E[now])
                {
                    long cost = D[ne];
                    int  ttt  = U[ne] == now ? V[ne] : U[ne];
                    if (min[t ^ 1][ttt] + cost == min[t ^ 1][now])
                    {
                        minedge.Add(ne);
                        comb[t][ttt] += comb[t][now]; if (comb[t][ttt] >= mod)
                        {
                            comb[t][ttt] -= mod;
                        }
                    }
                }
            }
        }

        long dmax = min[0][T];

        long total = (comb[0][T] * comb[1][S]) % mod;

        bool[] uused = new bool[N];
        long   remv  = 0;

        for (int i = 0; i < N; i++)
        {
            if (min[0][i] == dmax - min[0][i])
            {
                long c = (comb[0][i] * comb[1][i] % mod) * (comb[1][i] * comb[0][i] % mod) % mod;
                remv += c; if (remv >= mod)
                {
                    remv -= mod;
                }
            }
        }
        //Console.WriteLine(total);
        //Console.WriteLine(remv);

        foreach (var e in minedge)
        {
            int  u  = U[e];
            int  v  = V[e];
            long di = D[e];

            if (min[0][u] < min[0][v])
            {
                if (2 * min[0][u] < dmax && 2 * min[0][v] > dmax)
                {
                    long c = (comb[0][u] * comb[1][v] % mod) * (comb[1][v] * comb[0][u] % mod) % mod;
                    remv += c; if (remv >= mod)
                    {
                        remv -= mod;
                    }
                }
            }
            else if (min[0][u] > min[0][v])
            {
                if (2 * min[0][v] < dmax && 2 * min[0][u] > dmax)
                {
                    long c = (comb[0][v] * comb[1][u] % mod) * (comb[1][u] * comb[0][v] % mod) % mod;
                    remv += c; if (remv >= mod)
                    {
                        remv -= mod;
                    }
                }
            }
        }

        long ans = (total + mod - remv) % mod;

        Console.WriteLine(ans);
    }
Example #17
0
    public void Solve()
    {
        List <int>[] E = new List <int> [N];
        for (int i = 0; i < N; i++)
        {
            E[i] = new List <int>();
        }
        for (int i = 0; i < M; i++)
        {
            E[U[i]].Add(i);
            E[V[i]].Add(i);
        }

        long Inf = (long)1e18;

        long[][] min  = new long[2][];
        long[][] comb = new long[2][];
        for (int i = 0; i < 2; i++)
        {
            min[i] = new long[N];
            for (int j = 0; j < N; j++)
            {
                min[i][j] = Inf;
            }
            comb[i] = new long[N];
        }

        int[]  strt    = new int[] { S, T };
        bool[] minedge = new bool[M];


        for (int t = 0; t < 2; t++)
        {
            var    SH   = new SkewHeap <Pair>();
            bool[] used = new bool[N];
            SH.Push(new Pair(strt[t], 0));
            min[t][strt[t]]  = 0;
            comb[t][strt[t]] = 1;

            while (SH.Count > 0)
            {
                var p    = SH.Top; SH.Pop();
                var now  = p.Pos;
                var cost = p.Cost;
                if (used[now])
                {
                    continue;
                }
                used[now]   = true;
                min[t][now] = cost;
                foreach (var ne in E[now])
                {
                    long nc = cost + D[ne];
                    int  nv = U[ne] == now ? V[ne] : U[ne];
                    if (min[t][nv] > nc)
                    {
                        min[t][nv] = nc;
                        SH.Push(new Pair(nv, nc));
                    }

                    if (used[nv] && min[t][nv] + D[ne] == min[t][now])
                    {
                        comb[t][now] += comb[t][nv];                            // borrow
                        minedge[ne]   = true;
                        if (comb[t][now] >= mod)
                        {
                            comb[t][now] -= mod;
                        }
                    }
                }
            }
        }


        long dmax = min[0][T];

        long total = (comb[0][T] * comb[1][S]) % mod;
        long remv  = 0;

        for (int i = 0; i < N; i++)
        {
            if (min[0][i] == dmax - min[0][i])
            {
                long c = (comb[0][i] * comb[1][i] % mod) * (comb[1][i] * comb[0][i] % mod) % mod;
                remv += c; if (remv >= mod)
                {
                    remv -= mod;
                }
            }
        }

        for (int e = 0; e < M; e++)
        {
            int  u  = U[e];
            int  v  = V[e];
            long di = D[e];
            if (!minedge[e])
            {
                continue;
            }

            if (min[0][u] < min[0][v])
            {
                if (min[0][v] > dmax)
                {
                    continue;
                }
                if (min[0][u] + di != min[0][v])
                {
                    continue;
                }
                if (min[0][u] + min[1][v] + di != dmax)
                {
                    continue;
                }
                if (2 * min[0][u] < dmax && 2 * min[0][v] > dmax)
                {
                    long c = (comb[0][u] * comb[1][v] % mod) * (comb[1][v] * comb[0][u] % mod) % mod;
                    remv += c; if (remv >= mod)
                    {
                        remv -= mod;
                    }
                }
            }
            else if (min[0][u] > min[0][v])
            {
                if (min[0][u] > dmax)
                {
                    continue;
                }
                if (min[0][v] + di != min[0][u])
                {
                    continue;
                }
                if (min[0][v] + min[1][u] + di != dmax)
                {
                    continue;
                }
                if (2 * min[0][v] < dmax && 2 * min[0][u] > dmax)
                {
                    long c = (comb[0][v] * comb[1][u] % mod) * (comb[1][u] * comb[0][v] % mod) % mod;
                    remv += c; if (remv >= mod)
                    {
                        remv -= mod;
                    }
                }
            }
        }

        long ans = (total + mod - remv) % mod;

        Console.WriteLine(ans);
    }
Example #18
0
    public void Solve()
    {
        var ST = new SegTree[2];

        for (int i = 0; i < 2; i++)
        {
            ST[i] = new SegTree(N);
        }
        for (int i = 0; i < N; i++)
        {
            ST[i % 2].Update(i, A[i]);
        }

        List <int> ans = new List <int>();
        int        Inf = (int)1e9;

        var SH = new SkewHeap <Pair>();

        var minIdx = QueryMinIdx(0, N, ST);

        SH.Push(new Pair(0, N, A[minIdx[0]], A[minIdx[1]]));

        int[] Idx = new int[N + 2];
        for (int i = 0; i < N; i++)
        {
            Idx[A[i]] = i;
        }


        while (SH.Count > 0)
        {
            var p    = SH.Top; SH.Pop();
            int l    = p.L;
            int r    = p.R;
            int a    = p.A;
            int b    = p.B;
            int aidx = Idx[a];
            int bidx = Idx[b];

            ans.Add(a);
            ans.Add(b);
            ST[aidx % 2].Update(aidx, Inf);
            ST[bidx % 2].Update(bidx, Inf);
            if (aidx - l > 1)
            {
                var midx = QueryMinIdx(l, aidx, ST);
                SH.Push(new Pair(l, aidx, A[midx[0]], A[midx[1]]));
            }
            if (bidx - (aidx + 1) > 1)
            {
                var midx = QueryMinIdx(aidx + 1, bidx, ST);
                SH.Push(new Pair(aidx + 1, bidx, A[midx[0]], A[midx[1]]));
            }
            if (r - (bidx + 1) > 1)
            {
                var midx = QueryMinIdx(bidx + 1, r, ST);
                SH.Push(new Pair(bidx + 1, r, A[midx[0]], A[midx[1]]));
            }
        }

        Console.WriteLine(String.Join(" ", ans));
    }
Example #19
0
    public void Solve()
    {
        Dictionary <long, List <Pair2> > E = new Dictionary <long, List <Pair2> >();
        int  Ext = (int)1e7;
        long mod = (long)1e9 + 7;

        for (int i = 0; i < M; i++)
        {
            var p0 = P[i] * mod + C[i];
            var q0 = Q[i] * mod + C[i];
            var p1 = P[i] * mod + Ext;
            var q1 = Q[i] * mod + Ext;
            if (!E.ContainsKey(p0))
            {
                E.Add(p0, new List <Pair2>());
            }
            if (!E.ContainsKey(q0))
            {
                E.Add(q0, new List <Pair2>());
            }
            if (!E.ContainsKey(p1))
            {
                E.Add(p1, new List <Pair2>());
            }
            if (!E.ContainsKey(q1))
            {
                E.Add(q1, new List <Pair2>());
            }
            E[p0].Add(new Pair2(q0, 0));
            E[q0].Add(new Pair2(p0, 0));
            E[p0].Add(new Pair2(p1, 1));            // ???????????1
            E[q0].Add(new Pair2(q1, 1));
            E[p1].Add(new Pair2(p0, 0));
            E[q1].Add(new Pair2(q0, 0));
        }

        long Inf = (long)1e9;
        Dictionary <long, long> Min = new Dictionary <long, long>();
        var SH     = new SkewHeap <Pair2>();
        var pstart = 0 * mod + Ext;

        Min.Add(pstart, 0);
        SH.Push(new Pair2(pstart, 0));

        HashSet <long> done = new HashSet <long>();

        while (SH.Count > 0)
        {
            var now = SH.Top; SH.Pop();
            var p   = now.Pos;
            var c   = now.Cost;
            if (done.Contains(p))
            {
                continue;
            }
            done.Add(p);
            Min[p] = c;
            if (!E.ContainsKey(p))
            {
                continue;
            }
            foreach (var nxt in E[p])
            {
                var np = nxt.Pos;
                var nc = nxt.Cost;
                if (!Min.ContainsKey(np))
                {
                    Min.Add(np, Inf);
                }
                if (Min[np] <= c + nc)
                {
                    continue;
                }
                Min[np] = c + nc;
                SH.Push(new Pair2(np, c + nc));
            }
        }

        var pend = (N - 1) * mod + Ext;

        Console.WriteLine(Min.ContainsKey(pend) ? Min[pend] : -1);
    }