[problem:645A]↵
---↵
**Idea:** [user:yummy,2016-03-18]↵
↵
One solution is to just brute force and use DFS to try all the possibilities. Alternatively, note that two puzzles can be changed to each other if and only if the $A$, $B$, and $C$ have the same orientation—clockwise or counterclockwise—in the puzzle. A third option, since the number of possibilities is so small, is to simply classify all of the $4!=24$ configurations by hand.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
string b, b1, b2, e, e1, e2;↵
↵
int main(){↵
cin >> b1 >> b2 >> e1 >> e2;↵
swap(b2[0], b2[1]);↵
swap(e2[0], e2[1]);↵
b = b1 + b2;↵
e = e1 + e2;↵
b.erase(b.find('X'), 1);↵
e.erase(e.find('X'), 1);↵
if((b + b).find(e) != string::npos){↵
cout << "YES\n";↵
} else {↵
cout << "NO\n";↵
}↵
}↵
↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
[problem:645B]↵
---↵
**Idea: [user:ksun48,2016-03-18]**↵
↵
Loosely speaking, we’re trying to reverse the array as much as possible.↵
↵
Intuitively, the optimal solution seems to be to switch the first and last cow, then the second and second-to-last cow, and so on for $k$ minutes, unless the sequence is reversed already, in which case we are done. But how can we show that these moves give the optimal messiness?↵
↵
It is clear when $2\cdot k \ge n-1$ that we can reverse the array with this method.↵
↵
However, when $2\cdot k < n-1$, there are going to be cows that we must not have not moved a single time. Since in each move we swap at most $2$ cows, there must be at least $n-2\cdot k$ cows that we have not touched, with $p_i = i$. Two untouched cows $i$ and $j$ must have $p_i < p_j$, so there must be at least $\dfrac{(n-2\cdot k)(n-2\cdot k-1)}{2}$ pairs of cows which are ordered correctly.↵
↵
In fact, if we follow the above process, we get that $p_i = (n+1)-i$ for the first $k$ and last $k$ cows, while $p_i = i$ for the middle $n-2\cdot k$ cows. From this we can see that the both $i < j$ and $p_i < p_j$ happen only when $i$ and $j$ are in the middle $n-2 \cdot k$ cows. Therefore we know our algorithm is optimal.↵
↵
An $O(k)$ solution, therefore, is to count how many incorrectly ordered pairs $(i,j)$ are created at each step and add them up. When we swap cow $i$ and $(n+1)-i$ in step $i$, this creates $1 + 2\cdot(n-2i)$ more pairs. So the answer will be $\sum_{i=1}^{k} 1+2(n-2i)$.↵
↵
We can reduce this to $O(1)$ by using our earlier observation, that every pair except those $\dfrac{(n-2\cdot k)(n-2\cdot k-1)}{2}$ pairs are unordered, which gives $\dfrac{n(n-1)}{2} - \dfrac{(n-2\cdot k)(n-2\cdot k-1)}{2}$ total pairs $(i,j)$. Note that this does always not fit in a 32-bit integer.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵
typedef long long LL;↵
↵
int main(){↵
LL n, k;↵
cin >> n >> k;↵
LL c = max(n-2*k,0LL);↵
LL a = n*(n-1)/2-c*(c-1)/2;↵
cout << a << endl;↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
↵
[problem:645C]↵
---↵
**Idea: [user:GlebsHP,2016-03-18]**↵
↵
First, observe that the $k+1$ rooms that Farmer John books should be consecutive empty rooms. Thus we can loop over all such sets of rooms with a sliding window in linear time. To check the next set of rooms, we simply advance each endpoint of our interval to the next empty room. Every time we do this, we need to compute the optimal placement of Farmer John’s room. We can maintain the position of his room with two pointers—as we slide our window of rooms to the right, the optimal position of Farmer John’s room should always move to the right or remain the same. This solution runs in $O(n)$. ↵
↵
Alternatively, we can use binary search or an STL set to find the best placement for Farmer John’s room as we iterate over the intervals of rooms. The complexity of these approaches is $O(n\log n)$.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
int N, K, res = 1e9;↵
string S;↵
↵
int next(int i){ // finds the next empty room↵
do {↵
i += 1;↵
} while(i < N && S[i] == '1');↵
return i;↵
}↵
↵
int main(){↵
cin >> N >> K >> S;↵
int l = next(-1), m = l, r = l;↵
for(int i = 0; i < K; i++){ // sets up the sliding window↵
r = next(r);↵
}↵
while(r < N){↵
while(max(m - l, r - m) > max(next(m) - l, r - next(m))){↵
m = next(m);↵
}↵
res = min(res, max(m - l, r - m));↵
l = next(l);↵
r = next(r);↵
}↵
cout << res << 'n';↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645D]↵
---↵
**Idea: [user:abacadaea,2016-03-18]**↵
↵
The robots will become fully sorted if and only if there exists a path with $n$ vertices in the directed graph defined by the match results. Because it is guaranteed that the results are not contradictory, this graph must be directed and acyclic—a DAG. Thus we can compute the longest path in this DAG via dynamic programming or a toposort.↵
↵
We now have two cases. First, if the longest path contains $n$ vertices, then it must uniquely define the ordering of the robots. This means the answer is the time at which the last edge was added to this path. Otherwise, if the longest path has fewer than $n$ vertices, then multiple orderings satisfy the results and you should print $-1$. Note that this algorithm runs in $O(n + m)$.↵
↵
Another solution to this problem binary searches on the answer. For some $k$, consider only those edges that were added before time $k$. We can determine if the robots could be totally ordered at time $k$ by running a toposort and checking if the longest path covers all $n$ vertices. This might be more intuitive for some, but has a complexity of $O(n \log n)$.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
const int MAXN = 1000005;↵
int N, M, dp[MAXN], res[MAXN];↵
vector<pair<int,int>> adj[MAXN];↵
↵
int check(int v){↵
if(dp[v]) return dp[v];↵
dp[v] = 1;↵
for(auto p : adj[v]){↵
int n = p.first;↵
if(check(n) + 1 > dp[v]){↵
dp[v] = dp[n] + 1;↵
res[v] = max(res[n], p.second);↵
}↵
}↵
return dp[v];↵
}↵
↵
int main(){↵
scanf("%d%d", &N, &M);↵
for(int i = 0; i < M; i++){↵
int a, b;↵
scanf("%d%d", &a, &b);↵
a -= 1, b -= 1;↵
adj[a].push_back({b, i + 1});↵
}↵
for(int i = 0; i < N; i++){↵
if(check(i) == N){↵
printf("%dn", res[i]);↵
return 0;↵
}↵
}↵
printf("-1n");↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645E]↵
---↵
**Idea: [user:yummy,2016-03-18]**↵
↵
For simplicity, let’s represent the letters by $1, 2, \dots, k$ instead of actual characters. Let $a[i]$ denote the number of distinct subsequences of the string that end in the letter $i$. Appending the letter $j$ to a string only changes the value of $a[j]$. Note that the new $a[j]$ becomes $1 + \sum_{i = 1}^k a[i]$—we can have the single letter $j$, or append $j$ to any of our old subsequences.↵
↵
The key observation is that no matter what character $j$ we choose to append, $a[j]$ will always end up the same. This suggests a greedy algorithm—always appending the character $j$ with the smallest $a[j]$. But how do we know which $a[j]$ is minimal while maintaining their values modulo $10^9 + 7$?↵
↵
The final observation is that if the last occurrence of $j$ is after the last occurrence of $j'$ in our string, then $a[j] > a[j']$. This is true because appending $j$ to the string makes $a[j]$ larger than all other $a[i]$. So instead of choosing the minimum $a[i]$, we can always choose the letter that appeared least recently. Since the sequence of letters we append becomes periodic, our solution runs in $O(L + n + k\log k)$. Of course, we can also find the least recently used letter with less efficient approaches, obtaining solutions with complexity $O((L + n)k)$.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
typedef long long ll;↵
↵
const ll MOD = 1000000007;↵
const int MAXK = 26;↵
int N, K, last[MAXK], ord[MAXK];↵
ll dp[MAXK], sum;↵
string S;↵
↵
bool comp(int a, int b){↵
return last[a] < last[b];↵
}↵
↵
void append(int c){↵
sum = (sum - dp[c] + MOD) % MOD;↵
dp[c] = (dp[c] + sum + 1) % MOD;↵
sum = (sum + dp[c]) % MOD;↵
}↵
↵
int main(){↵
cin >> N >> K >> S;↵
fill(last, last + K, -1);↵
for(int i = 0; i < S.size(); i++){↵
int c = S[i] - 'a';↵
last[c] = i;↵
append(c);↵
}↵
iota(ord, ord + K, 0);↵
sort(ord, ord + K, comp);↵
for(int i = 0; i < N; i++){↵
int c = ord[i % K];↵
append(c);↵
}↵
cout << (sum + 1) % MOD << 'n';↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645F]↵
---↵
**Idea: [user:desert97,2016-03-18]**↵
↵
After each query, the problem is essentially asking us to compute the sum of $\gcd(f_1, f_2, \cdots, f_k)$ for each choice of $k$ flowers. One quickly notes that it is too slow to loop over all choices of $k$ flowers, as there could be up to $\dbinom{n+q}{k}$ choices of $k$ species.↵
↵
So how can we compute a sum over $\dbinom{n+q}{k}$ terms? Well, we will definitely need to use the properties of the gcd function. If we figure out for each integer $a$ how many times $\gcd(f_1, f_2, \cdots, f_k) = a$ occurs in the sum (let this be $g(a)$), then our answer will be equal to $\displaystyle \sum_{a} a \cdot g(a)$ overall all $a$. In all of these sums, $a \le 10^6$.↵
↵
It seems that if $d(a)$ is the number of multiples of $a$ in our sequence, then there are $\dbinom{d(a)}{k}$ $k$-tuples which have gcd $a$. Yet there is something wrong with this reasoning: some of those $k$-tuples can have gcd $2a$, or $3a$, or any multiple of $a$. In fact, $\dbinom{d(a)}{k} = \displaystyle \sum_{a|m} g(m)$. ↵
↵
We will try to write $\displaystyle \sum_{a} a \cdot g(a)$ as a sum of these $\displaystyle \sum_{a|m} g(m)$.↵
We’ll take an example, when $a$ ranges from $1$ to $4$. The sum we wish to compute is $g(1) + 2g(2) + 3g(3) + 4g(4)$ which can be written as↵
↵
$$(g(1)+g(2)+g(3)+g(4)) + (g(2)+g(4)) + 2(g(3)) + 2(g(4)),$$↵
↵
or ↵
↵
$$\displaystyle \sum_{1|m} g(m) + \displaystyle \sum_{2|m} g(m) + 2\displaystyle \sum_{3|m} g(m) + 2\displaystyle \sum_{4|m} g(m).$$↵
↵
In general, we want to find coefficients $p_i$ such that we can write $\displaystyle \sum_{a} a \cdot g(a)$ as $\displaystyle \sum_{i} p_i \left ( \sum_{i|m} g(m) \right ) = \displaystyle \sum_{i} p_i \dbinom{d(i)}{k}$. Equating coefficients of $g(a)$ on both sides, we get that $a = \displaystyle \sum_{i \mid a} p_i$. (The mathematically versed reader will note that $p_i = \varphi(i)$, Euler's totient function, but this is not necessary to solve the problem.)↵
↵
We can thus precalculate all $p_i$ in $O(\max(a_i,c_i))$ using a recursive formula: $q_i = a - \displaystyle \sum_{i \mid a, i \neq a} p_i$. We can also precalculate $\dbinom{l}{k}$ for each $l \le 200000$, so in order to output $\displaystyle \sum_{i=1}^{1000000} p_i \dbinom{d(i)}{k}$ after each query we should keep track of the values of the function $d(i)$, the number of multiples of $i$.↵
When receiving $c_i$ flowers, we only need to update $d$ for the divisors of $c_i$ and add $\dbinom{d+1}{k}-\dbinom{d}{k}$. If we precompute the list of divisors of every integer using a sieve or sqrt checking, each update requires $O(number of divisors)$.↵
↵
Thus the complexity of this algorithm is $O(A \log A)$ or $O(A \sqrt{A})$ preprocessing, and $O((n+q)max(divisors))$.↵
↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
typedef long long ll;↵
↵
const ll MOD = 1000000007;↵
const int MAXN = 200005;↵
const int MAXA = 1000005;↵
int N, K, Q, A[MAXN];↵
int use[MAXA], phi[MAXA], cnt[MAXA];↵
vector<int> divisors[MAXA];↵
ll bin[MAXN], res;↵
↵
ll inv(ll a, ll p){↵
if(a == 1) return 1;↵
return (p - p / a) * inv(p % a, p) % p;↵
}↵
↵
void read(){↵
scanf("%d%d%d", &N, &K, &Q);↵
for(int i = 0; i < N + Q; i++){↵
scanf("%d", &A[i]);↵
use[A[i]] = 1;↵
}↵
}↵
↵
void init(){↵
iota(phi, phi + MAXA, 0);↵
for(int i = 1; i < MAXA; i++){↵
for(int j = i; j < MAXA; j += i){↵
if(i != j) phi[j] -= phi[i];↵
if(use[j]) divisors[j].push_back(i);↵
}↵
}↵
bin[K - 1] = 1;↵
for(int i = K; i < MAXN; i++){↵
bin[i] = bin[i - 1] * i % MOD * inv(i - K + 1, MOD) % MOD;↵
}↵
}↵
↵
int main(){↵
read();↵
init();↵
for(int i = 0; i < N + Q; i++){↵
for(int d : divisors[A[i]]){↵
res = (res + bin[cnt[d]] * phi[d]) % MOD;↵
cnt[d] += 1;↵
}↵
if(i >= N){↵
printf("%dn", res);↵
}↵
}↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645G]↵
---↵
**Idea: [user:yummy,2016-03-18]**↵
↵
Thanks to [user:TooDifficultIt,2016-03-18] and [user:Petr,2016-03-18] for sharing a solution with me that is much more intuitive than the one I originally had in mind! We’ll be updating our editorial with that approach soon.↵
↵
We begin by binary searching on the the minimum possible difference. Thus we wish to solve the decision problem "Can a difference of $k$ be achieved?" Consider the hyperbola $|PX - QX| = k$. Note that our answer is affirmative if and only if a pair of outposts defines a line that does not intersect the hyperbola.↵
↵
Our next step is a reduction to an equivalent decision problem on a circle through a projective transformation. We express this transformation as the composition of two simpler operations. The first is an affine map that takes the hyperbola $|PX - QX| = k$ to the unit hyperbola. The second maps homogenous coordinates $(x, y, z)$ to $(z, y, x)$. Under the latter, the unit hyperbola $x^2 - y^2 = z^2$ goes to the unit circle $x^2 + y^2 = z^2$.↵
↵
Because projective transformations preserve collinearity, a line intersecting the hyperbola is equivalent to a line intersecting the circle. Thus we want to know if any pair of the outposts' images defines a line that does not intersect the circle. We now map the image of each outpost to the minor arc on the unit circle defined by its tangents. (We disregard any points lying inside the circle.) Observe that our condition is equivalent to the existence of two intersecting arcs, neither of which contains the other. Verifying that two such arcs exist can be done with a priority queue and a radial sweep line in $O(n\log n)$.↵
↵
The total complexity of our solution is therefore $O(n \log n\log P)$, where $P$ is the precision that we need.↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
typedef long double ld;↵
↵
const ld EPS = 1e-12;↵
const ld PI = acos(-1);↵
const int MAXN = 100005;↵
int N;↵
ld A, X[MAXN], Y[MAXN];↵
↵
bool check(ld m){↵
ld u = m / 2;↵
ld v = sqrt(A * A - u * u);↵
vector<pair<ld,ld>> ev;↵
for(int i = 0; i < N; i++){↵
ld x = 1, y = Y[i] / v, alpha;↵
if(X[i] != 0){↵
x *= u / X[i], y *= u / X[i];↵
ld r = sqrt(x * x + y * y);↵
if(r < 1) continue;↵
alpha = acos(1 / r);↵
} else {↵
alpha = PI / 2;↵
}↵
ld base = atan2(y, x) - alpha;↵
if(base < 0) base += 2 * PI;↵
ev.push_back({base, base + 2 * alpha});↵
}↵
priority_queue<ld, vector<ld>, greater<ld>> pq;↵
sort(ev.begin(), ev.end());↵
for(int i = 0; i < 2; i++){↵
for(int j = 0; j < ev.size(); j++){↵
while(pq.size() && pq.top() < ev[j].first) pq.pop();↵
if(pq.size() && pq.top() < ev[j].second) return 1;↵
pq.push(ev[j].second);↵
ev[j].first += 2 * PI;↵
ev[j].second += 2 * PI;↵
}↵
}↵
return 0;↵
}↵
↵
int main(){↵
ios::sync_with_stdio(0);↵
cin >> N >> A;↵
for(int i = 0; i < N; i++){↵
cin >> X[i] >> Y[i];↵
}↵
ld lo = 0, hi = 2 * A;↵
while(hi - lo > EPS){↵
ld mid = (lo + hi) / 2;↵
(check(mid) ? hi : lo) = mid;↵
}↵
cout << fixed << setprecision(10);↵
cout << (lo + hi) / 2 << 'n';↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
---↵
**Idea:** [user:yummy,2016-03-18]↵
↵
One solution is to just brute force and use DFS to try all the possibilities. Alternatively, note that two puzzles can be changed to each other if and only if the $A$, $B$, and $C$ have the same orientation—clockwise or counterclockwise—in the puzzle. A third option, since the number of possibilities is so small, is to simply classify all of the $4!=24$ configurations by hand.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
string b, b1, b2, e, e1, e2;↵
↵
int main(){↵
cin >> b1 >> b2 >> e1 >> e2;↵
swap(b2[0], b2[1]);↵
swap(e2[0], e2[1]);↵
b = b1 + b2;↵
e = e1 + e2;↵
b.erase(b.find('X'), 1);↵
e.erase(e.find('X'), 1);↵
if((b + b).find(e) != string::npos){↵
cout << "YES\n";↵
} else {↵
cout << "NO\n";↵
}↵
}↵
↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
---↵
**Idea: [user:ksun48,2016-03-18]**↵
↵
Loosely speaking, we’re trying to reverse the array as much as possible.↵
↵
Intuitively, the optimal solution seems to be to switch the first and last cow, then the second and second-to-last cow, and so on for $k$ minutes, unless the sequence is reversed already, in which case we are done. But how can we show that these moves give the optimal messiness?↵
↵
It is clear when $2\cdot k \ge n-1$ that we can reverse the array with this method.↵
↵
However, when $2\cdot k < n-1$, there are going to be cows that we must not have not moved a single time. Since in each move we swap at most $2$ cows, there must be at least $n-2\cdot k$ cows that we have not touched, with $p_i = i$. Two untouched cows $i$ and $j$ must have $p_i < p_j$, so there must be at least $\dfrac{(n-2\cdot k)(n-2\cdot k-1)}{2}$ pairs of cows which are ordered correctly.↵
↵
In fact, if we follow the above process, we get that $p_i = (n+1)-i$ for the first $k$ and last $k$ cows, while $p_i = i$ for the middle $n-2\cdot k$ cows. From this we can see that the both $i < j$ and $p_i < p_j$ happen only when $i$ and $j$ are in the middle $n-2 \cdot k$ cows. Therefore we know our algorithm is optimal.↵
↵
An $O(k)$ solution, therefore, is to count how many incorrectly ordered pairs $(i,j)$ are created at each step and add them up. When we swap cow $i$ and $(n+1)-i$ in step $i$, this creates $1 + 2\cdot(n-2i)$ more pairs. So the answer will be $\sum_{i=1}^{k} 1+2(n-2i)$.↵
↵
We can reduce this to $O(1)$ by using our earlier observation, that every pair except those $\dfrac{(n-2\cdot k)(n-2\cdot k-1)}{2}$ pairs are unordered, which gives $\dfrac{n(n-1)}{2} - \dfrac{(n-2\cdot k)(n-2\cdot k-1)}{2}$ total pairs $(i,j)$. Note that this does always not fit in a 32-bit integer.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include<bits/stdc++.h>↵
using namespace std;↵
typedef long long LL;↵
↵
int main(){↵
LL n, k;↵
cin >> n >> k;↵
LL c = max(n-2*k,0LL);↵
LL a = n*(n-1)/2-c*(c-1)/2;↵
cout << a << endl;↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
↵
[problem:645C]↵
---↵
**Idea: [user:GlebsHP,2016-03-18]**↵
↵
First, observe that the $k+1$ rooms that Farmer John books should be consecutive empty rooms. Thus we can loop over all such sets of rooms with a sliding window in linear time. To check the next set of rooms, we simply advance each endpoint of our interval to the next empty room. Every time we do this, we need to compute the optimal placement of Farmer John’s room. We can maintain the position of his room with two pointers—as we slide our window of rooms to the right, the optimal position of Farmer John’s room should always move to the right or remain the same. This solution runs in $O(n)$. ↵
↵
Alternatively, we can use binary search or an STL set to find the best placement for Farmer John’s room as we iterate over the intervals of rooms. The complexity of these approaches is $O(n\log n)$.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
int N, K, res = 1e9;↵
string S;↵
↵
int next(int i){ // finds the next empty room↵
do {↵
i += 1;↵
} while(i < N && S[i] == '1');↵
return i;↵
}↵
↵
int main(){↵
cin >> N >> K >> S;↵
int l = next(-1), m = l, r = l;↵
for(int i = 0; i < K; i++){ // sets up the sliding window↵
r = next(r);↵
}↵
while(r < N){↵
while(max(m - l, r - m) > max(next(m) - l, r - next(m))){↵
m = next(m);↵
}↵
res = min(res, max(m - l, r - m));↵
l = next(l);↵
r = next(r);↵
}↵
cout << res << 'n';↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645D]↵
---↵
**Idea: [user:abacadaea,2016-03-18]**↵
↵
The robots will become fully sorted if and only if there exists a path with $n$ vertices in the directed graph defined by the match results. Because it is guaranteed that the results are not contradictory, this graph must be directed and acyclic—a DAG. Thus we can compute the longest path in this DAG via dynamic programming or a toposort.↵
↵
We now have two cases. First, if the longest path contains $n$ vertices, then it must uniquely define the ordering of the robots. This means the answer is the time at which the last edge was added to this path. Otherwise, if the longest path has fewer than $n$ vertices, then multiple orderings satisfy the results and you should print $-1$. Note that this algorithm runs in $O(n + m)$.↵
↵
Another solution to this problem binary searches on the answer. For some $k$, consider only those edges that were added before time $k$. We can determine if the robots could be totally ordered at time $k$ by running a toposort and checking if the longest path covers all $n$ vertices. This might be more intuitive for some, but has a complexity of $O(n \log n)$.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
const int MAXN = 1000005;↵
int N, M, dp[MAXN], res[MAXN];↵
vector<pair<int,int>> adj[MAXN];↵
↵
int check(int v){↵
if(dp[v]) return dp[v];↵
dp[v] = 1;↵
for(auto p : adj[v]){↵
int n = p.first;↵
if(check(n) + 1 > dp[v]){↵
dp[v] = dp[n] + 1;↵
res[v] = max(res[n], p.second);↵
}↵
}↵
return dp[v];↵
}↵
↵
int main(){↵
scanf("%d%d", &N, &M);↵
for(int i = 0; i < M; i++){↵
int a, b;↵
scanf("%d%d", &a, &b);↵
a -= 1, b -= 1;↵
adj[a].push_back({b, i + 1});↵
}↵
for(int i = 0; i < N; i++){↵
if(check(i) == N){↵
printf("%dn", res[i]);↵
return 0;↵
}↵
}↵
printf("-1n");↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645E]↵
---↵
**Idea: [user:yummy,2016-03-18]**↵
↵
For simplicity, let’s represent the letters by $1, 2, \dots, k$ instead of actual characters. Let $a[i]$ denote the number of distinct subsequences of the string that end in the letter $i$. Appending the letter $j$ to a string only changes the value of $a[j]$. Note that the new $a[j]$ becomes $1 + \sum_{i = 1}^k a[i]$—we can have the single letter $j$, or append $j$ to any of our old subsequences.↵
↵
The key observation is that no matter what character $j$ we choose to append, $a[j]$ will always end up the same. This suggests a greedy algorithm—always appending the character $j$ with the smallest $a[j]$. But how do we know which $a[j]$ is minimal while maintaining their values modulo $10^9 + 7$?↵
↵
The final observation is that if the last occurrence of $j$ is after the last occurrence of $j'$ in our string, then $a[j] > a[j']$. This is true because appending $j$ to the string makes $a[j]$ larger than all other $a[i]$. So instead of choosing the minimum $a[i]$, we can always choose the letter that appeared least recently. Since the sequence of letters we append becomes periodic, our solution runs in $O(L + n + k\log k)$. Of course, we can also find the least recently used letter with less efficient approaches, obtaining solutions with complexity $O((L + n)k)$.↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
typedef long long ll;↵
↵
const ll MOD = 1000000007;↵
const int MAXK = 26;↵
int N, K, last[MAXK], ord[MAXK];↵
ll dp[MAXK], sum;↵
string S;↵
↵
bool comp(int a, int b){↵
return last[a] < last[b];↵
}↵
↵
void append(int c){↵
sum = (sum - dp[c] + MOD) % MOD;↵
dp[c] = (dp[c] + sum + 1) % MOD;↵
sum = (sum + dp[c]) % MOD;↵
}↵
↵
int main(){↵
cin >> N >> K >> S;↵
fill(last, last + K, -1);↵
for(int i = 0; i < S.size(); i++){↵
int c = S[i] - 'a';↵
last[c] = i;↵
append(c);↵
}↵
iota(ord, ord + K, 0);↵
sort(ord, ord + K, comp);↵
for(int i = 0; i < N; i++){↵
int c = ord[i % K];↵
append(c);↵
}↵
cout << (sum + 1) % MOD << 'n';↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645F]↵
---↵
**Idea: [user:desert97,2016-03-18]**↵
↵
After each query, the problem is essentially asking us to compute the sum of $\gcd(f_1, f_2, \cdots, f_k)$ for each choice of $k$ flowers. One quickly notes that it is too slow to loop over all choices of $k$ flowers, as there could be up to $\dbinom{n+q}{k}$ choices of $k$ species.↵
↵
So how can we compute a sum over $\dbinom{n+q}{k}$ terms? Well, we will definitely need to use the properties of the gcd function. If we figure out for each integer $a$ how many times $\gcd(f_1, f_2, \cdots, f_k) = a$ occurs in the sum (let this be $g(a)$), then our answer will be equal to $\displaystyle \sum_{a} a \cdot g(a)$ overall all $a$. In all of these sums, $a \le 10^6$.↵
↵
It seems that if $d(a)$ is the number of multiples of $a$ in our sequence, then there are $\dbinom{d(a)}{k}$ $k$-tuples which have gcd $a$. Yet there is something wrong with this reasoning: some of those $k$-tuples can have gcd $2a$, or $3a$, or any multiple of $a$. In fact, $\dbinom{d(a)}{k} = \displaystyle \sum_{a|m} g(m)$. ↵
↵
We will try to write $\displaystyle \sum_{a} a \cdot g(a)$ as a sum of these $\displaystyle \sum_{a|m} g(m)$.↵
We’ll take an example, when $a$ ranges from $1$ to $4$. The sum we wish to compute is $g(1) + 2g(2) + 3g(3) + 4g(4)$ which can be written as↵
↵
$$(g(1)+g(2)+g(3)+g(4)) + (g(2)+g(4)) + 2(g(3)) + 2(g(4)),$$↵
↵
or ↵
↵
$$\displaystyle \sum_{1|m} g(m) + \displaystyle \sum_{2|m} g(m) + 2\displaystyle \sum_{3|m} g(m) + 2\displaystyle \sum_{4|m} g(m).$$↵
↵
In general, we want to find coefficients $p_i$ such that we can write $\displaystyle \sum_{a} a \cdot g(a)$ as $\displaystyle \sum_{i} p_i \left ( \sum_{i|m} g(m) \right ) = \displaystyle \sum_{i} p_i \dbinom{d(i)}{k}$. Equating coefficients of $g(a)$ on both sides, we get that $a = \displaystyle \sum_{i \mid a} p_i$. (The mathematically versed reader will note that $p_i = \varphi(i)$, Euler's totient function, but this is not necessary to solve the problem.)↵
↵
We can thus precalculate all $p_i$ in $O(\max(a_i,c_i))$ using a recursive formula: $q_i = a - \displaystyle \sum_{i \mid a, i \neq a} p_i$. We can also precalculate $\dbinom{l}{k}$ for each $l \le 200000$, so in order to output $\displaystyle \sum_{i=1}^{1000000} p_i \dbinom{d(i)}{k}$ after each query we should keep track of the values of the function $d(i)$, the number of multiples of $i$.↵
When receiving $c_i$ flowers, we only need to update $d$ for the divisors of $c_i$ and add $\dbinom{d+1}{k}-\dbinom{d}{k}$. If we precompute the list of divisors of every integer using a sieve or sqrt checking, each update requires $O(number of divisors)$.↵
↵
Thus the complexity of this algorithm is $O(A \log A)$ or $O(A \sqrt{A})$ preprocessing, and $O((n+q)max(divisors))$.↵
↵
↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
typedef long long ll;↵
↵
const ll MOD = 1000000007;↵
const int MAXN = 200005;↵
const int MAXA = 1000005;↵
int N, K, Q, A[MAXN];↵
int use[MAXA], phi[MAXA], cnt[MAXA];↵
vector<int> divisors[MAXA];↵
ll bin[MAXN], res;↵
↵
ll inv(ll a, ll p){↵
if(a == 1) return 1;↵
return (p - p / a) * inv(p % a, p) % p;↵
}↵
↵
void read(){↵
scanf("%d%d%d", &N, &K, &Q);↵
for(int i = 0; i < N + Q; i++){↵
scanf("%d", &A[i]);↵
use[A[i]] = 1;↵
}↵
}↵
↵
void init(){↵
iota(phi, phi + MAXA, 0);↵
for(int i = 1; i < MAXA; i++){↵
for(int j = i; j < MAXA; j += i){↵
if(i != j) phi[j] -= phi[i];↵
if(use[j]) divisors[j].push_back(i);↵
}↵
}↵
bin[K - 1] = 1;↵
for(int i = K; i < MAXN; i++){↵
bin[i] = bin[i - 1] * i % MOD * inv(i - K + 1, MOD) % MOD;↵
}↵
}↵
↵
int main(){↵
read();↵
init();↵
for(int i = 0; i < N + Q; i++){↵
for(int d : divisors[A[i]]){↵
res = (res + bin[cnt[d]] * phi[d]) % MOD;↵
cnt[d] += 1;↵
}↵
if(i >= N){↵
printf("%dn", res);↵
}↵
}↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵
↵
[problem:645G]↵
---↵
**Idea: [user:yummy,2016-03-18]**↵
↵
Thanks to [user:TooDifficu
↵
We begin by binary searching on the the minimum possible difference. Thus we wish to solve the decision problem "Can a difference of $k$ be achieved?" Consider the hyperbola $|PX - QX| = k$. Note that our answer is affirmative if and only if a pair of outposts defines a line that does not intersect the hyperbola.↵
↵
Our next step is a reduction to an equivalent decision problem on a circle through a projective transformation. We express this transformation as the composition of two simpler operations. The first is an affine map that takes the hyperbola $|PX - QX| = k$ to the unit hyperbola. The second maps homogenous coordinates $(x, y, z)$ to $(z, y, x)$. Under the latter, the unit hyperbola $x^2 - y^2 = z^2$ goes to the unit circle $x^2 + y^2 = z^2$.↵
↵
Because projective transformations preserve collinearity, a line intersecting the hyperbola is equivalent to a line intersecting the circle. Thus we want to know if any pair of the outposts' images defines a line that does not intersect the circle. We now map the image of each outpost to the minor arc on the unit circle defined by its tangents. (We disregard any points lying inside the circle.) Observe that our condition is equivalent to the existence of two intersecting arcs, neither of which contains the other. Verifying that two such arcs exist can be done with a priority queue and a radial sweep line in $O(n\log n)$.↵
↵
The total complexity of our solution is therefore $O(n \log n\log P)$, where $P$ is the precision that we need.↵
↵
↵
↵
↵
↵
↵
<spoiler summary="Code">↵
~~~~~↵
#include <bits/stdc++.h>↵
using namespace std;↵
↵
typedef long double ld;↵
↵
const ld EPS = 1e-12;↵
const ld PI = acos(-1);↵
const int MAXN = 100005;↵
int N;↵
ld A, X[MAXN], Y[MAXN];↵
↵
bool check(ld m){↵
ld u = m / 2;↵
ld v = sqrt(A * A - u * u);↵
vector<pair<ld,ld>> ev;↵
for(int i = 0; i < N; i++){↵
ld x = 1, y = Y[i] / v, alpha;↵
if(X[i] != 0){↵
x *= u / X[i], y *= u / X[i];↵
ld r = sqrt(x * x + y * y);↵
if(r < 1) continue;↵
alpha = acos(1 / r);↵
} else {↵
alpha = PI / 2;↵
}↵
ld base = atan2(y, x) - alpha;↵
if(base < 0) base += 2 * PI;↵
ev.push_back({base, base + 2 * alpha});↵
}↵
priority_queue<ld, vector<ld>, greater<ld>> pq;↵
sort(ev.begin(), ev.end());↵
for(int i = 0; i < 2; i++){↵
for(int j = 0; j < ev.size(); j++){↵
while(pq.size() && pq.top() < ev[j].first) pq.pop();↵
if(pq.size() && pq.top() < ev[j].second) return 1;↵
pq.push(ev[j].second);↵
ev[j].first += 2 * PI;↵
ev[j].second += 2 * PI;↵
}↵
}↵
return 0;↵
}↵
↵
int main(){↵
ios::sync_with_stdio(0);↵
cin >> N >> A;↵
for(int i = 0; i < N; i++){↵
cin >> X[i] >> Y[i];↵
}↵
ld lo = 0, hi = 2 * A;↵
while(hi - lo > EPS){↵
ld mid = (lo + hi) / 2;↵
(check(mid) ? hi : lo) = mid;↵
}↵
cout << fixed << setprecision(10);↵
cout << (lo + hi) / 2 << 'n';↵
}↵
~~~~~↵
</spoiler>↵
↵
↵
↵
↵
↵
↵