# 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 2)

### 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 2)

#### P.Fear Factoring

The Slivians are afraid of factoring; it’s just, well, difficult.

Really, they don’t even care about the factors themselves, just how much they sum to.

We can define $F(n)$ as the sum of all of the factors of n; so $F(6) = 12$ and $F(12) = 28$. Your task is, given two integers a and b with $a \leq b$, to calculate $$S = \sum_{a \leq n \leq b} F(n)$$

Input

The input consists of a single line containing space-separated integers $a$ and $b$ $(1 \leq a \leq b \leq 10 ^ {12}, b − a \leq 10 ^ 6)$.

Output

Print $S$ on a single line

#### Code：

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll a, b;

ll Solve(ll x) {
ll ans = 0;
for(ll i = 1; i <= x; ) {
ll nx = x / (x / i);
ll v = x / i;
ll c1 = (i + nx), c2 = (nx - i + 1);
if(c1 & 1) c2 /= 2;
else c1 /= 2;
ll c = c1 * c2;
ans += v * c;
i = nx + 1;
}
return ans;
}

int main() {
scanf("%lld%lld", &a, &b);
printf("%lld\n", Solve(b) - Solve(a - 1));
return 0;
}


#### R.Straight Shot

You have a toy robot that walks straight at a constant speed $v$, and you wish for it to travel on the two-dimensional plane from $(0, 0)$ to $(X, 0)$. If the plane were empty, you could start the robot facing straight east from the origin, and it would walk there in $X/v$ time. Unfortunately, between the start and the destination are n moving sidewalks, each moving directly north or south, which affect the robot’s position while it is walking.

The direction that robot is facing is not changed by the sidewalks; the robot will face in the same orientation for the entire duration of its walk. These sidewalks are aligned with the $y$-$axis$ and are infinitely long. You still must get the robot to go from start to finish, but you’ll need to adjust the orientation of the robot at the start. Given that you choose this direction correctly, so that the robot arrives exactly at the destination, how long will it take the robot to get there?

One final caveat: You don’t want the toy robot to walk for too long. If the robot cannot reach the destination in at most twice the time it would take in the absence of all moving sidewalks ($i.e., 2X/v$), indicate this.

Input

The first line consists of three space-separated numbers $n, X,$ and $v (0 ≤ n ≤ 100, 1 ≤ X ≤ 1,000,000, 1.0 ≤ v ≤ 100.0).$ Note that $v$ is not necessarily an integer.

Each of the next n lines contains three space-separated numbers $l_i , r_i ,$ and $v_i (0 ≤ l_1 < r_1 ≤ l_2 < r_2 ≤ \cdots ≤ l_n < r_n ≤ X; −100.0 ≤ v_i ≤ 100.0),$ describing the ith moving sidewalk. The integer $l_i$ denotes the left edge of the sidewalk, the integer $r_i$ denotes the right edge of the sidewalk, and the decimal number $v_i$ denotes the speed of the sidewalk. A positive speed means the sidewalk moves north, while a negative speed means the sidewalk moves south.

Output

If the robot cannot reach the destination in at most twice the time it would take in the absence of all moving sidewalks, output $“Too hard”$ on a single line (without quotation marks). Otherwise, output, on a single line, the travel time of the robot from the start to the destination, rounded and displayed to exactly three decimal places.

#### Code：

#include <bits/stdc++.h>
using namespace std;
const int N = 105;
const double eps = 1e-6;

int n;
double l[N], r[N], v[N];
double X, V, sum;

int main() {
scanf("%d%lf%lf", &n, &X, &V);
double T = X / V;
for(int i = 1; i <= n; i++) scanf("%lf%lf%lf", &l[i], &r[i], &v[i]), sum += (r[i] - l[i]) * v[i];
double Vy = - sum / X;
if(V * V - Vy * Vy < eps) return puts("Too hard"), 0;
double Vx = sqrt(V * V - Vy * Vy);

double t = X / Vx;
if(T * 2.0 - t <= eps) return puts("Too hard"), 0;
printf("%.3f\n", t);
return 0;
}


#### T.Security Badge

You are in charge of the security for a large building, with $n$ rooms and $m$ doors between the rooms. The rooms and doors are conveniently numbered from $1$ to $n$, and from $1$ to $m$, respectively.

Door i opens from room $a_i$ to room $b_i$ , but not the other way around. Additionally, each door has
a security code that can be represented as a range of numbers $[c_i , d_i].$

There are $k$ employees working in the building, each carrying a security badge with a unique, integer-valued badge ID between $1$ and $k$. An employee is cleared to go through door $i$ only when the badge ID $x$ satisfies $c_i ≤ x ≤ d_i.$

Your boss wants a quick check of the security of the building. Given $s$ and $t$, how many employees can go from room $s$ to room $t$?

Input

The first line of input contains three space-separated integers $n, m,$ and $k (2 ≤ n ≤ 1,000, 1 ≤ m ≤ 5,000, 1 ≤ k ≤ 109 ).$

The second line of input contains two space-separated integers $s$ and $t (1 ≤ s, t ≤ n; s \neq t).$
Each of the next m lines contains four space-separated integers $a_i , b_i , c_i,$ and $d_i (1 ≤ a_i , b_i ≤ n, 1 ≤ c_i ≤ d_i ≤ k, a_i \neq b_i)$, describing door $i$.

For any given pair of rooms $a$, $b$ there will be at most one door from $a$ to $b$ (but there may be both a door from $a$ to $b$ and a door from $b$ to $a$)

Output

Print, on a single line, the number of employees who can reach room $t$ starting from room $s$

#### Code：

#include <bits/stdc++.h>
using namespace std;
const int N = 5005;

struct edge {
int to, nxt, l, r, f;
}E[N << 2];
int head[N], s[N << 2], vis[N];
int tot, n, m, S, T, k, t, las, ans;

void Addedge(int u, int v, int l, int r) {
E[++tot].to = v; E[tot].nxt = head[u]; head[u] = tot; E[tot].l = l; E[tot].r = r; E[tot].f = 0;
}

queue<int> Q;

int Bfs() {
while(!Q.empty()) Q.pop();
Q.push(S);
memset(vis, 0, sizeof vis);

while(!Q.empty()) {
int o = Q.front(); Q.pop();
vis[o] = 1;
if(o == T) return 1;
for(int i = head[o]; ~i; i = E[i].nxt) {
int to = E[i].to;
if(E[i].f && !vis[to]) Q.push(to);
}
}
return 0;
}

void Check(int L, int R) {
for(int i = 1; i <= tot; i++) {
E[i].f = 0;
if(E[i].l <= L && E[i].r >= R) E[i].f = 1;
}
if(Bfs()) ans += R - max(las, L) + 1, las = R + 1;
}

int main() {
memset(head, -1, sizeof head);
scanf("%d%d%d%d%d", &n, &m, &k, &S, &T);
for(int i = 1, u, v, l, r; i <= m; i++) {
scanf("%d%d%d%d", &u, &v, &l, &r);
Addedge(u, v, l, r);
s[++t] = l; s[++t] = r;
}
sort(s + 1, s + 1 + t);
for(int i = 1; i < t; i++) Check(s[i], s[i + 1]);
printf("%d\n", ans);
return 0;
}


#### W.Grid Coloring

You have an $m$-by-$n$ grid of squares that you wish to color. You may color each square either red or blue, subject to the following constraints:

• Every square must be colored.
• Colors of some squares are already decided (red or blue), and cannot be changed.
• For each blue square, all squares in the rectangle from the top left of the grid to that square must also be blue.

Given these constraints, how many distinct colorings of the grid are there? The grid cannot be
rotated.

Input

The first line of input consists of two space-separated integers $m$ and $n (1 ≤ m, n ≤ 30).$ Each of the next $m$ lines contains $n$ characters, representing the grid. Character ‘B’ indicates squares that are already colored blue. Similarly, ‘R’ indicates red squares. Character ‘.’ indicates squares that are not colored yet.

Output

Print, on a single line, the number of distinct colorings possible.

#### Code：

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 35;

int n, m;
int Mp[N][N], dn[N], up[N];
ll f[N][N];
char s[N];

void ColorB(int x, int y) {
for(int i = 1; i <= x; i++) {
for(int j = 1; j <= y; j++) {
if(!Mp[i][j] || Mp[i][j] == -1) Mp[i][j] = -1;
else {
puts("0");
exit(0);
}
}
}
return ;
}

void ColorR(int x, int y) {
for(int i = x; i <= n; i++) {
for(int j = y; j <= m; j++) {
if(!Mp[i][j] || Mp[i][j] == 1) Mp[i][j] = 1;
else {
puts("0");
exit(0);
}
}
}
}

int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf("%s", s + 1);
for(int j = 1; j <= m; j++) {
if(s[j] == 'R') Mp[i][j] = 1;
else if(s[j] == 'B') Mp[i][j] = -1;
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
if(Mp[i][j] == -1) ColorB(i, j);
else if(Mp[i][j] == 1) ColorR(i, j);
}
}
for(int j = 1; j <= m; j++) {
int fs = n + 1;
for(int i = 1; i <= n; i++) {
if(!Mp[i][j]) {
dn[j] = i;
if(!up[j]) up[j] = i;
}
if(Mp[i][j] == 1) fs = min(fs, i);
}
if(!up[j]) up[j] = dn[j] = fs;
else dn[j]++;
}
f[0][n + 1] = 1;
for(int i = 1; i <= m; i++) {
for(int j = up[i]; j <= dn[i]; j++) {
for(int k = n + 1; k >= j; k--) {
f[i][j] += f[i - 1][k];
}
}
}
ll ans = 0;
for(int i = up[m]; i <= dn[m]; i++) ans += f[m][i];
printf("%lld\n", ans);
return 0;
}


posted @ 2019-04-10 14:47  Apocrypha  阅读(404)  评论(0编辑  收藏  举报