标签:intval ++ vmax ever sum reverse token imp false
problem A link
problem B link
problem C link
problem D link
首先枚举vip的数量$x$,那么首先需要为这$x$选取$x$个位置,为$C_{n}^{x}$。剩下的$n-x$是50和100的个数。
设$f(n,L,R)$表示$n$个50和100,最后剩余50的个数为$[L,R]$范围,满足这些的合法顺序的方案数。那么答案为:$answer=\sum_{i=0}^{n}C_{n}^{i}f(n-i,L,R)$
现在考虑如何计算$f(n,L,R)$。
首先假设$n$中50和100的个数相等的答案,即$f(n,0,0),n$为偶数。这样的合法序列可以看作一条从$(0,0)$到$(n,0)$的折线,从$(x_{i},y_{i})$到$(x_{i}+1,y_{i+1})$时,需满足$|y_{i}-y_{i+1}|=1$且$y_{i}\ge 0,y_{i+1}\ge 0$。所有的情况有$C_{n}^{\frac{2}{2}}$个。但是这些中有不合法的情况。假设这条折线在$(x_{t},y_{t})$时第一次出现$y_{t}<0$的情况,即$y_{t}=-1$。现在将$(0,0)$到$x_{t},y_{t}$之间的折线部分按照直线$y=-1$作一个对称,那么现在的折线变成了从点$(0,-2)$到点$(n,0)$。那么所有的从$(0,0)$到$(n,0)$的不合法的折线都会对应到一条从$(0,-2)$到点$(n,0)$的折线。而从$(0,-2)$到点$(n,0)$折线有$C_{n}^{\frac{n}{2}-1}$种(因为要选择$\frac{n}{2}-1$条向下)。所以$f(n,0,0)=C_{n}^{\frac{n}{2}}-C_{n}^{\frac{n}{2}-1}$。
problem E link
code for problem A
import java.util.Scanner; public class Main { String s = "What are you doing at the end of the world? Are you busy? Will you save us?"; String A = "What are you doing while sending \""; String B = "\"? Are you busy? Will you send \""; String C = "\"?"; long[] f = new long[61]; public static void main(String[] args) { new Main().cal(); } void cal() { f[0] = s.length(); int t = A.length() + B.length() + C.length(); for (int i = 1; i <= 60; ++ i) { f[i] = f[i - 1] * 2 + t; } Scanner in = new Scanner(System.in); StringBuilder sb = new StringBuilder(); int q = in.nextInt(); for (int i = 0; i < q; ++ i) { int n = in.nextInt(); long k = in.nextLong(); sb.append(get(n, k)); } System.out.println(sb.toString()); } char get(int n, Long k) { int t = A.length(); while (n > 54) { if (k <= t) { return A.charAt(k.intValue() - 1); } k -= t; n -= 1; } if (k > f[n]) { return ‘.‘; } while (n > 0) { if (k <= A.length()) { return A.charAt(k.intValue() - 1); } k -= A.length(); if (f[n - 1] >= k) { n -= 1; continue; } k -= f[n - 1]; if (k <= B.length()) { return B.charAt(k.intValue() - 1); } k -= B.length(); if (f[n - 1] >= k) { n -= 1; continue; } k -= f[n - 1]; return C.charAt(k.intValue() - 1); } return s.charAt(k.intValue() - 1); } }
code for problem B
import java.util.Scanner; public class Main { public static void main(String[] args) { new Main().cal(); } int n; int m; int c; int[] p = null; void cal() { Scanner in = new Scanner(System.in); n = in.nextInt(); m = in.nextInt(); c = in.nextInt(); p = new int[n]; for (int i = 0; i < m; ++ i) { int x = in.nextInt(); int pos = add(x); p[pos] = x; System.out.println(pos + 1); System.out.flush(); if (finish()) { return; } } } int add(int x) { if (x <= c / 2) { int id = 0; while (p[id] != 0 && p[id] <= x) { id ++; } return id; } else { int id = n - 1; while (p[id] != 0 && p[id] >= x) { id --; } return id; } } boolean finish() { for (int i = 0; i < n; ++ i) { if (p[i] == 0) { return false; } } return true; } }
code for problem C
import java.util.Arrays; import java.util.Comparator; import java.util.Scanner; public class Main { public static void main(String[] args) { new Main().cal(); } static class Pair { long val; int cnt; Pair() {} Pair(long val, int cnt) { this.val = val; this.cnt = cnt; } } static class PairComparator implements Comparator<Pair> { @Override public int compare(Pair a, Pair b) { return a.val < b.val ? -1 : 1; } } int n; int m; int seed; int vmax; Pair[] b = null; Pair[] c = null; int bSize = 0; int cSize = 0; int rnd() { int ret = seed; seed = (int)((seed * 7L + 13) % 1000000007); return ret; } void cal() { Scanner in = new Scanner(System.in); n = in.nextInt(); m = in.nextInt(); seed = in.nextInt(); vmax = in.nextInt(); b = new Pair[n]; c = new Pair[n]; b[bSize ++] = new Pair(rnd() % vmax + 1, 1); for (int i = 2; i <= n; ++ i) { int val = rnd() % vmax + 1; if (val == b[bSize - 1].val) { b[bSize - 1].cnt += 1; } else { b[bSize ++] = new Pair(val, 1); } } for (int i = 0; i < m; ++ i) { int op = rnd() % 4 + 1; int left = rnd() % n + 1; int right = rnd() % n + 1; if (left > right) { int tmp = left; left = right; right = tmp; } int x = 0; int y = 0; if (op == 3) { x = rnd() % (right - left + 1) + 1; } else { x = rnd() % vmax + 1; } if (op == 4) { y = rnd() % vmax + 1; } if (op == 1 || op == 2) { operation1or2(left, right, x, op == 1); } else if (op == 3) { operation3(left, right, x); } else { operation4(left, right, x, y); } } } void operation1or2(int left, int right, int x, boolean isOperation1) { int L = 0, R = 0; cSize = 0; for (int i = 0; i < bSize; ++ i) { L = R + 1; R = L + b[i].cnt - 1; add(b[i].val, intersect(L, left - 1, L, R)); if (isOperation1) { add(b[i].val + x, intersect(left, right , L, R)); } else { add(x, intersect(left, right , L, R)); } add(b[i].val, intersect(right + 1, R, L, R)); } for (int i = 0; i < cSize; ++ i) { b[i] = c[i]; } bSize = cSize; } void operation3(int left, int right, int kth) { int L = 0, R = 0; cSize = 0; for (int i = 0; i < bSize; ++ i) { L = R + 1; R = L + b[i].cnt - 1; int cnt = intersect(left, right , L, R); if (cnt > 0) { c[cSize ++] = new Pair(b[i].val, cnt); } } Arrays.sort(c, 0, cSize, new PairComparator()); for (int i = 0; i < cSize; ++ i) { if (c[i].cnt >= kth) { System.out.println(c[i].val); return; } kth -= c[i].cnt; } } void operation4(int left, int right, int x, int y) { int L = 0, R = 0; long result = 0; for (int i = 0; i < bSize; ++ i) { L = R + 1; R = L + b[i].cnt - 1; int cnt = intersect(left, right , L, R); if (cnt > 0) { result += Pow(b[i].val, x, y) * cnt % y; result %= y; } } System.out.println(result); } int intersect(int left1, int right1, int left2, int right2) { int left = Math.max(left1, left2); int right = Math.min(right1, right2); return Math.max(0, right - left + 1); } void add(long val, int cnt) { if (cnt == 0) { return; } if (cSize > 0 && c[cSize - 1].val == val) { c[cSize - 1].cnt += cnt; } else { c[cSize ++] = new Pair(val, cnt); } } static long Pow(long a, int b, int mod) { long result = 1; a %= mod; while (b != 0) { if (b % 2 == 1) { result = result * a % mod; } a = a * a % mod; b >>= 1; } return result; } }
code for problem D
import java.util.*; public class Main { public static void main(String[] args) { new Main().cal(); } int n; int p; int left; int right; long[] fact = null; int[] primes = null; void init() { primes = split(p); fact = new long[n + 1]; fact[0] = 1; for (int i = 1; i <= n; ++ i) { int k = i; for (int prime : primes) { while (k % prime == 0) { k /= prime; } } fact[i] = fact[i - 1] * k % p; } } void cal() { Scanner in = new Scanner(System.in); n = in.nextInt(); p = in.nextInt(); left = in.nextInt(); right = in.nextInt(); if (p == 1) { System.out.println(0); return; } init(); long result = 0; for (int cNum = 0; cNum <= n; ++ cNum) { long t = calculate(cNum, (cNum + left + 1) / 2) - calculate(cNum, (cNum + right) / 2 + 1); t %= p; t *= calculate(n, cNum); t %= p; result += t; result %= p; } if (result < 0) { result += p; } System.out.println(result); } long calculate(int n, int m) { if (m < 0 || m > n) { return 0; } if (m == 0 || m == n) { return 1; } long result = fact[n] * reverse(fact[m] * fact[n - m] % p, p) % p; for (int prime : primes) { int cnt = count(n, prime) - count(m, prime) - count(n - m, prime); result = result * Pow(prime, cnt, p) % p; } return result; } static int count(int n, int p) { int cnt = 0; while (n > 0) { cnt += n / p; n /= p; } return cnt; } static long Pow(long a, long b, long mod) { long result = 1; while (b > 0) { if (b % 2 == 1) { result = result * a % mod; } a = a * a % mod; b >>= 1; } return result; } static long reverse(long a, long b) { long[] r = exGcd(a,b); return (r[1] % b + b) % b; } static long[] exGcd(long a,long b) { if (b == 0) { return new long[]{a, 1, 0}; } long[] result = exGcd(b, a % b); return new long[]{result[0], result[2], result[1] - a / b * result[2]}; } static int[] split(int x) { List<Integer> list = new ArrayList<>(); for (int i = 2; i * i <= x; ++ i) { if (x % i == 0) { list.add(i); while (x % i == 0) { x /= i; } } } if (x > 1) { list.add(x); } int[] result = new int[list.size()]; for (int i = 0; i < list.size(); ++ i) { result[i] = list.get(i); } return result; } }
code for problem E
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.*; public class Main { public static void main(String[] args) { new Main(); } static class FastIO { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(System.out); StringTokenizer st = null; String nextToken() { while (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(bufferedReader.readLine()); } catch (IOException e) { throw new RuntimeException(e); } } return st.nextToken(); } int nextInt() { return Integer.parseInt(nextToken()); } void output(Object object) { out.println(object); } void finish() { out.close(); } } FastIO fastIO = new FastIO(); Main() { cal(); fastIO.finish(); } static class Block { int nMin; int nMax; int left; int right; int off; int[] parent = null; int[] c = null; Block(int left, int right, int[] a) { this.left = left; this.right = right; this.off = 0; nMin = 1; nMax = Integer.MIN_VALUE; for (int i = left; i <= right; ++ i) { nMax = Math.max(nMax, a[i]); } parent = new int[nMax + 1]; c = new int[nMax + 1]; for (int i = left; i <= right; ++ i) { c[a[i]] += 1; } for (int i = 0; i < nMax + 1; ++ i) { parent[i] = i; } } int getRoot(int x) { if (parent[x] != x) { parent[x] = getRoot(parent[x]); } return parent[x]; } void rebuild(int L, int R, int[] a, int x) { if (L == left && R == right) { rebuildAll(x); return; } for (int i = left; i <= right; ++ i) { a[i] = getRoot(a[i]); } for (int i = L; i <= R; ++ i) { if (a[i] - off > x) { c[a[i]] -= 1; a[i] -= x; c[a[i]] += 1; } } } void rebuildAll(int x) { if (nMax - nMin + 1 <= x) { return; } if (nMin + x + x - 1 <= nMax) { off += x; for (int i = nMin; i < nMin + x; ++ i) { parent[i] = i + x; c[i + x] += c[i]; c[i] = 0; } nMin += x; } else { for (int i = nMin + x; i <= nMax; ++ i) { parent[i] = i - x; c[i - x] += c[i]; c[i] = 0; } nMax = nMin + x - 1; } } int query(int L, int R, int[] a, int x) { if (L == left && R == right) { return queryAll(x); } x += off; int cnt = 0; for (int i = L; i <= R; ++ i) { if (getRoot(a[i]) == x) { cnt += 1; } } return cnt; } int queryAll(int x) { if (nMin <= x + off && x + off <= nMax) { return c[x + off]; } return 0; } } static final int BLOCK_SIZE = 333; int n; int m; int[] a = null; Block[] b = null; void cal() { n = fastIO.nextInt(); m = fastIO.nextInt(); a = new int[n]; for (int i = 0; i < n; ++ i) { a[i] = fastIO.nextInt(); } final int nBlockNum = (n - 1) / BLOCK_SIZE + 1; b = new Block[nBlockNum]; for (int i = 0; i < nBlockNum; ++ i) { int left = i * BLOCK_SIZE; int right = Math.min(n - 1, left + BLOCK_SIZE - 1); b[i] = new Block(left, right, a); } for (int i = 0; i < m; ++ i) { int op = fastIO.nextInt(); int left = fastIO.nextInt() - 1; int right = fastIO.nextInt() - 1; int x = fastIO.nextInt(); int lBlockIndex = left / BLOCK_SIZE; int rBlockIndex = right / BLOCK_SIZE; if (op == 1) { if (lBlockIndex == rBlockIndex) { b[lBlockIndex].rebuild(left, right, a, x); } else { b[lBlockIndex].rebuild(left, b[lBlockIndex].right, a, x); b[rBlockIndex].rebuild(b[rBlockIndex].left, right, a, x); for (int j = lBlockIndex + 1; j <= rBlockIndex - 1; ++ j) { b[j].rebuildAll(x); } } } else { int result = 0; if (lBlockIndex == rBlockIndex) { result += b[lBlockIndex].query(left, right, a, x); } else { result += b[lBlockIndex].query(left, b[lBlockIndex].right, a, x); result += b[rBlockIndex].query(b[rBlockIndex].left, right, a, x); for (int j = lBlockIndex + 1; j <= rBlockIndex - 1; ++ j) { result += b[j].queryAll(x); } } fastIO.output(result); } } } }
标签:intval ++ vmax ever sum reverse token imp false
原文地址:http://www.cnblogs.com/jianglangcaijin/p/7977991.html