标签: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