Submission #950053


Source Code Expand

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

public class Main {
  void run() {
    int n = ni();
    if (n > 3000) {
      int v = 0 / 0;
    }
    TreeSet<Integer> notExistInPset = new TreeSet<>();
    for (int i = 0; i < n; ++i) {
      notExistInPset.add(i);
    }
    int[] p = new int[n];
    int k = 0;
    int[] countWildCardUntilPrev = new int[n];
    for (int i = 0; i < n; ++i) {
      countWildCardUntilPrev[i] = k;
      p[i] = ni() - 1;
      if (p[i] < 0) {
        ++k;
      } else {
        notExistInPset.remove(p[i]);
      }
    }
    int sumOfNotExistInP = notExistInPset.stream().reduce(0, (a, b) -> a + b);

    long[] factorial = new long[n + 1];
    factorial[0] = 1;
    for (int i = 1; i <= n; ++i) {
      factorial[i] = i * factorial[i - 1];
      factorial[i] %= MOD;
    }

    int[] countIfSjSmallerThanSi = new int[n];
    BIT<Integer> bit = new BIT<>(n, (a, b) -> a + b, () -> 0);
    for (int i = 0; i < n; ++i) {
      if (p[i] >= 0) {
        bit.update(p[i] + 1, 1);
        countIfSjSmallerThanSi[i] = bit.reduce(p[i], () -> 0);
      }
    }

    ArrayList<Integer> notExitstInPlist = new ArrayList<>(notExistInPset);
    Collections.sort(notExitstInPlist);

    long unko = 0;
    if (k > 1) {
      ArrayList<Integer> list = new ArrayList<>(notExistInPset);
      for (int si : list) {
        notExistInPset.remove(si);
        int num = notExistInPset.headSet(si).size();
        unko += num * factorial[k - 2];
        unko %= MOD;
        notExistInPset.add(si);
      }
    }

    long sum = 0;
    for (int i = 0; i < n; ++i) {
      long sub = 0;
      if (p[i] >= 0) {
        sub += p[i] * factorial[k];
        sub %= MOD;
        sub -= countIfSjSmallerThanSi[i] * factorial[k];
        sub += (Math.abs(sub / MOD) + 1) * MOD;
        sub %= MOD;
        if (k > 0) {
//          int num = notExistInPset.headSet(p[i]).size();
          int num = -Collections.binarySearch(notExitstInPlist, p[i]) - 1;
          sub -= num * factorial[k - 1] * countWildCardUntilPrev[i];
          sub += (Math.abs(sub / MOD) + 1) * MOD;
          sub %= MOD;
        }
      } else {
        sub += sumOfNotExistInP * factorial[k - 1];
        sub %= MOD;
        for (int j = 0; j < i; ++j) {
          if (p[j] < 0) continue;
//          int num = notExistInPset.tailSet(p[j]).size();
          int num = -Collections.binarySearch(notExitstInPlist, p[j]) - 1;
          num = notExitstInPlist.size() - num;
          sub -= num * factorial[k - 1];
          sub += (Math.abs(sub / MOD) + 1) * MOD;
          sub %= MOD;
        }
        ArrayList<Integer> list = new ArrayList<>(notExistInPset);
        if (k > 1) {
//          for (int si : list) {
//            notExistInPset.remove(si);
//            int num = notExistInPset.headSet(si).size();
//            sub -= num * factorial[k - 2] * countWildCardUntilPrev[i];
//            sub += (Math.abs(sub / MOD) + 1) * MOD;
//            sub %= MOD;
//            notExistInPset.add(si);
//          }
          sub -= (unko * countWildCardUntilPrev[i]) % MOD;
          sub += (Math.abs(sub / MOD) + 1) * MOD;
          sub %= MOD;
        }
      }
      sub *= factorial[n - 1 - i];
      sub %= MOD;
      sum += sub;
      sum %= MOD;
    }
    sum += factorial[k];
    sum %= MOD;

    System.out.println(sum);
  }

  Scanner sc = new Scanner(System.in);

  public static void main(String[] args) {
    new Main().run();
  }

  int ni() {
    return Integer.parseInt(sc.next());
  }

  void debug(Object... os) {
    System.err.println(Arrays.deepToString(os));
  }

  class BIT<T> {
    int n;
    ArrayList<T> bit;
    BiFunction<T, T, T> bif;

    BIT(int n, BiFunction<T, T, T> bif, Supplier<T> sup) {
      this.n = n;
      bit = new ArrayList<>(n + 1);
      for (int i = 0; i < n + 1; ++i) {
        bit.add(sup.get());
      }
      this.bif = bif;
    }

    void update(int i, T v) {
      for (int x = i; x <= n; x += x & -x) {
        bit.set(x, bif.apply(bit.get(x), v));
      }
    }

    T reduce(int i, Supplier<T> sup) {
      T ret = sup.get();
      for (int x = i; x > 0; x -= x & -x) {
        ret = bif.apply(ret, bit.get(x));
      }
      return ret;
    }
  }

  long MOD = 1_000_000_007;

  long pow(long a, long r) {
    long sum = 1;
    while (r > 0) {
      if ((r & 1) == 1) {
        sum *= a;
        sum %= MOD;
      }
      a *= a;
      a %= MOD;
      r >>= 1;
    }
    return sum;
  }

  long C(int n, int r) {
    long sum = 1;
    for (int i = n; 0 < i; --i) {
      sum *= i;
      sum %= MOD;
    }
    long s = 1;
    for (int i = r; 0 < i; --i) {
      s *= i;
      s %= MOD;
    }
    sum *= pow(s, MOD - 2);
    sum %= MOD;

    long t = 1;
    for (int i = n - r; 0 < i; --i) {
      t *= i;
      t %= MOD;
    }
    sum *= pow(t, MOD - 2);
    sum %= MOD;

    return sum;
  }

  double GOLDEN_RATIO = (1.0 + Math.sqrt(5)) / 2.0;

  /**
   * 黄金分割探索
   *
   * @param left  下限
   * @param right 上限
   * @param f     探索する関数
   * @param comp  上に凸な関数を探索するときは、Comparator.comparingDouble(Double::doubleValue)
   *              下に凸な関数を探索するときは、Comparator.comparingDouble(Double::doubleValue).reversed()
   * @return 極値の座標x
   */
  double goldenSectionSearch(double left, double right, Function<Double, Double> f, Comparator<Double> comp) {
    double c1 = divideInternally(left, right, 1, GOLDEN_RATIO);
    double c2 = divideInternally(left, right, GOLDEN_RATIO, 1);
    double d1 = f.apply(c1);
    double d2 = f.apply(c2);
    while (right - left > 1e-9) {
      if (comp.compare(d1, d2) > 0) {
        right = c2;
        c2 = c1;
        d2 = d1;
        c1 = divideInternally(left, right, 1, GOLDEN_RATIO);
        d1 = f.apply(c1);
      } else {
        left = c1;
        c1 = c2;
        d1 = d2;
        c2 = divideInternally(left, right, GOLDEN_RATIO, 1);
        d2 = f.apply(c2);
      }
    }
    return right;
  }

  /**
   * [a,b]をm:nに内分する点を返す
   */
  double divideInternally(double a, double b, double m, double n) {
    return (n * a + m * b) / (m + n);
  }
}

Submission Info

Submission Time
Task E - Encyclopedia of Permutations
User arukuka
Language Java8 (OpenJDK 1.8.0)
Score 500
Code Size 6473 Byte
Status RE
Exec Time 663 ms
Memory 34388 KB

Judge Result

Set Name Sample Subtask All
Score / Max Score 0 / 0 500 / 500 0 / 700
Status
AC × 5
AC × 33
AC × 33
RE × 25
Set Name Test Cases
Sample 0_000.txt, 0_001.txt, 0_002.txt, 0_003.txt, 0_004.txt
Subtask 0_000.txt, 0_001.txt, 0_002.txt, 0_003.txt, 0_004.txt, 1_005.txt, 1_006.txt, 1_007.txt, 1_008.txt, 1_009.txt, 1_010.txt, 1_011.txt, 1_012.txt, 1_013.txt, 1_014.txt, 1_015.txt, 1_016.txt, 1_017.txt, 1_018.txt, 1_019.txt, 1_020.txt, 1_021.txt, 1_022.txt, 1_023.txt, 1_024.txt, 1_025.txt, 1_026.txt, 1_027.txt, 1_028.txt, 1_029.txt, 1_030.txt, 1_031.txt, 1_032.txt
All 0_000.txt, 0_001.txt, 0_002.txt, 0_003.txt, 0_004.txt, 1_005.txt, 1_006.txt, 1_007.txt, 1_008.txt, 1_009.txt, 1_010.txt, 1_011.txt, 1_012.txt, 1_013.txt, 1_014.txt, 1_015.txt, 1_016.txt, 1_017.txt, 1_018.txt, 1_019.txt, 1_020.txt, 1_021.txt, 1_022.txt, 1_023.txt, 1_024.txt, 1_025.txt, 1_026.txt, 1_027.txt, 1_028.txt, 1_029.txt, 1_030.txt, 1_031.txt, 1_032.txt, 2_033.txt, 2_034.txt, 2_035.txt, 2_036.txt, 2_037.txt, 2_038.txt, 2_039.txt, 2_040.txt, 2_041.txt, 2_042.txt, 2_043.txt, 2_044.txt, 2_045.txt, 2_046.txt, 2_047.txt, 2_048.txt, 2_049.txt, 2_050.txt, 2_051.txt, 2_052.txt, 2_053.txt, 2_054.txt, 2_055.txt, 2_056.txt, 2_057.txt
Case Name Status Exec Time Memory
0_000.txt AC 217 ms 15432 KB
0_001.txt AC 217 ms 15436 KB
0_002.txt AC 219 ms 15416 KB
0_003.txt AC 212 ms 15308 KB
0_004.txt AC 219 ms 15304 KB
1_005.txt AC 222 ms 15432 KB
1_006.txt AC 223 ms 15560 KB
1_007.txt AC 215 ms 15312 KB
1_008.txt AC 621 ms 33476 KB
1_009.txt AC 418 ms 25612 KB
1_010.txt AC 636 ms 33728 KB
1_011.txt AC 526 ms 32304 KB
1_012.txt AC 644 ms 32876 KB
1_013.txt AC 367 ms 19668 KB
1_014.txt AC 663 ms 34388 KB
1_015.txt AC 408 ms 24716 KB
1_016.txt AC 644 ms 32932 KB
1_017.txt AC 220 ms 15300 KB
1_018.txt AC 580 ms 31576 KB
1_019.txt AC 409 ms 21444 KB
1_020.txt AC 528 ms 31848 KB
1_021.txt AC 377 ms 20672 KB
1_022.txt AC 506 ms 30544 KB
1_023.txt AC 435 ms 23360 KB
1_024.txt AC 451 ms 26088 KB
1_025.txt AC 234 ms 15180 KB
1_026.txt AC 354 ms 20016 KB
1_027.txt AC 313 ms 17128 KB
1_028.txt AC 561 ms 32420 KB
1_029.txt AC 293 ms 18500 KB
1_030.txt AC 323 ms 19128 KB
1_031.txt AC 313 ms 18520 KB
1_032.txt AC 629 ms 30684 KB
2_033.txt RE 125 ms 9548 KB
2_034.txt RE 124 ms 9548 KB
2_035.txt RE 125 ms 9552 KB
2_036.txt RE 123 ms 9552 KB
2_037.txt RE 124 ms 9680 KB
2_038.txt RE 122 ms 9676 KB
2_039.txt RE 122 ms 9552 KB
2_040.txt RE 122 ms 9552 KB
2_041.txt RE 122 ms 9672 KB
2_042.txt RE 123 ms 9548 KB
2_043.txt RE 124 ms 9812 KB
2_044.txt RE 122 ms 9680 KB
2_045.txt RE 124 ms 9552 KB
2_046.txt RE 123 ms 9552 KB
2_047.txt RE 123 ms 9552 KB
2_048.txt RE 122 ms 9556 KB
2_049.txt RE 122 ms 9680 KB
2_050.txt RE 124 ms 9552 KB
2_051.txt RE 124 ms 9680 KB
2_052.txt RE 122 ms 9548 KB
2_053.txt RE 124 ms 9552 KB
2_054.txt RE 123 ms 9680 KB
2_055.txt RE 124 ms 9540 KB
2_056.txt RE 123 ms 9676 KB
2_057.txt RE 124 ms 9552 KB