1207A - There Are Two Types Of Burgers
Идея: BledDest
Разбор
Tutorial is loading...
Решение (Roms)
#include <bits/stdc++.h>
using namespace std;
int t;
int b, p, f;
int h, c;
int main() {
cin >> t;
for(int tc = 0; tc < t; ++tc){
cin >> b >> p >> f;
cin >> h >> c;
b /= 2;
if(h < c){
swap(h, c);
swap(p, f);
}
int res = 0;
int cnt = min(b, p);
b -= cnt, p -= cnt;
res += h * cnt;
cnt = min(b, f);
b -= cnt, f -= cnt;
res += c * cnt;
cout << res << endl;
}
return 0;
}
Идея: BledDest
Разбор
Tutorial is loading...
Решение (BledDest)
n, m = map(int, input().split())
a = [[] for i in range(n)]
for i in range(n):
a[i] = list(map(int, input().split()))
ans = []
for i in range(n - 1):
for j in range(m - 1):
if(a[i][j] * a[i][j + 1] * a[i + 1][j] * a[i + 1][j + 1] > 0):
a[i][j] = 2
a[i + 1][j] = 2
a[i][j + 1] = 2
a[i + 1][j + 1] = 2
ans.append([i, j])
cnt1 = 0
for i in range(n):
for j in range(m):
if(a[i][j] == 1):
cnt1 += 1
if(cnt1 != 0):
print(-1)
else:
print(len(ans))
for x in ans:
print(x[0] + 1, x[1] + 1)
Идея: adedalic
Разбор
Tutorial is loading...
Решение (adedalic)
const val INF64 = 1e18.toLong()
fun main(args: Array<String>) {
val tc = readLine()!!.toInt()
for (t in 1..tc) {
val (n, a, b) = readLine()!!.split(' ').map { it.toInt() }
val s = readLine()!!
val d = Array(n + 1) { arrayOf(INF64, INF64) }
d[0][0] = b.toLong()
for (pos in 0 until n) {
if (s[pos] == '0') {
d[pos + 1][0] = minOf(d[pos + 1][0], d[pos][0] + a + b)
d[pos + 1][1] = minOf(d[pos + 1][1], d[pos][0] + 2 * (a + b))
d[pos + 1][1] = minOf(d[pos + 1][1], d[pos][1] + a + 2 * b)
d[pos + 1][0] = minOf(d[pos + 1][0], d[pos][1] + 2 * a + b)
} else {
d[pos + 1][1] = minOf(d[pos + 1][1], d[pos][1] + a + 2 * b)
}
}
println(d[n][0])
}
}
1207D - Number Of Permutations
Идея: Roms
Разбор
Tutorial is loading...
Решение (Roms)
#include <bits/stdc++.h>
using namespace std;
const int N = int(3e5) + 99;
const int MOD = 998244353;
int mul(int a, int b){
return (a * 1LL * b) % MOD;
}
int sum(int a, int b){
return (a + b) % MOD;
}
int n;
pair<int, int> a[N];
int f[N];
int main() {
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d%d", &a[i].first, &a[i].second);
f[0] = 1;
for(int i = 1; i < N; ++i)
f[i] = mul(i, f[i - 1]);
int res = f[n];
for(int c = 0; c < 2; ++c){
int d = 1;
sort(a, a + n);
int l = 0;
while(l < n){
int r = l + 1;
while(r < n && a[l].first == a[r].first) ++r;
d = mul(d, f[r - l]);
l = r;
}
res = sum(res, MOD - d);
for(int i = 0; i < n; ++i)
swap(a[i].first, a[i].second);
}
sort(a, a + n);
int l = 0;
int d = 1;
while(l < n){
int r = l + 1;
while(r < n && a[l].first == a[r].first) ++r;
map<int, int> m;
for(int i = l; i < r; ++i) ++m[a[i].second];
for(auto p : m) d = mul(d, f[p.second]);
l = r;
}
for(int i = 1; i < n; ++i)
if(a[i - 1].second > a[i].second) d = 0;
res = sum(res, d);
printf("%d\n", res);
return 0;
}
Идея: adedalic, Neon, BledDest
Разбор
Tutorial is loading...
Решение (BledDest)
#include<bits/stdc++.h>
using namespace std;
int main()
{
cout << "?";
for(int i = 1; i <= 100; i++)
cout << " " << i;
cout << endl;
cout.flush();
int res1;
cin >> res1;
cout << "?";
for(int i = 1; i <= 100; i++)
cout << " " << (i << 7);
cout << endl;
cout.flush();
int res2;
cin >> res2;
int x = 0;
x |= (res1 & (((1 << 7) - 1) << 7));
x |= (res2 & ((1 << 7) - 1));
cout << "! " << x << endl;
cout.flush();
return 0;
}
Идея: BledDest
Разбор
Tutorial is loading...
Решение (BledDest)
#include <bits/stdc++.h>
using namespace std;
const int N = 500043;
const int K = 750;
int a[N];
int sum[K][K];
int main()
{
int q;
scanf("%d", &q);
for(int i = 0; i < q; i++)
{
int t, x, y;
scanf("%d %d %d", &t, &x, &y);
if(t == 1)
{
a[x] += y;
for(int i = 1; i < K; i++)
sum[i][x % i] += y;
}
else
{
if(x >= K)
{
int ans = 0;
for(int i = y; i <= 500000; i += x)
ans += a[i];
printf("%d\n", ans);
}
else
printf("%d\n", sum[x][y]);
}
}
return 0;
}
Идея: adedalic
Разбор
Tutorial is loading...
Решение (PikMike)
#include <bits/stdc++.h>
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
const int AL = 26;
const int N = 400 * 1000 + 13;
struct node{
int nxt[AL];
node(){
memset(nxt, -1, sizeof(nxt));
}
int& operator [](int x){
return nxt[x];
}
};
struct node_at{
int nxt[AL];
int p;
char pch;
int link;
int go[AL];
node_at(){
memset(nxt, -1, sizeof(nxt));
memset(go, -1, sizeof(go));
link = p = -1;
}
int& operator [](int x){
return nxt[x];
}
};
int cntnm;
node trienm[N];
int cntqr;
node_at trieqr[N];
int add_string(string s){
int v = 0;
for (auto it : s){
int c = it - 'a';
if (trieqr[v][c] == -1){
trieqr[cntqr] = node_at();
trieqr[cntqr].p = v;
trieqr[cntqr].pch = c;
trieqr[v][c] = cntqr;
++cntqr;
}
v = trieqr[v][c];
}
return v;
}
int go(int v, int c);
int get_link(int v){
if (trieqr[v].link == -1){
if (v == 0 || trieqr[v].p == 0)
trieqr[v].link = 0;
else
trieqr[v].link = go(get_link(trieqr[v].p), trieqr[v].pch);
}
return trieqr[v].link;
}
int go(int v, int c) {
if (trieqr[v].go[c] == -1){
if (trieqr[v][c] != -1)
trieqr[v].go[c] = trieqr[v][c];
else
trieqr[v].go[c] = (v == 0 ? 0 : go(get_link(v), c));
}
return trieqr[v].go[c];
}
int add_letter(int v, int c){
if (trienm[v][c] == -1){
trienm[cntnm] = node();
trienm[v][c] = cntnm;
++cntnm;
}
return trienm[v][c];
}
vector<int> g[N];
int tin[N], tout[N], T;
void dfs_init(int v){
tin[v] = T++;
for (auto u : g[v])
dfs_init(u);
tout[v] = T;
}
int f[N];
void upd(int v, int val){
for (int i = tin[v]; i < N; i |= i + 1)
f[i] += val;
}
int get(int x){
int sum = 0;
for (int i = x; i >= 0; i = (i & (i + 1)) - 1)
sum += f[i];
return sum;
}
int sum(int v){
return get(tout[v] - 1) - get(tin[v] - 1);
}
int n, m;
int nm[N], qr[N];
vector<int> nms[N];
vector<int> reqs[N];
int ans[N];
void dfs(int v, int cur){
upd(cur, 1);
for (auto it : nms[v])
for (auto q : reqs[it])
ans[q] = sum(qr[q]);
forn(i, AL) if (trienm[v][i] != -1)
dfs(trienm[v][i], go(cur, i));
upd(cur, -1);
}
int main(){
cntqr = 0;
trieqr[cntqr++] = node_at();
cntnm = 0;
trienm[cntnm++] = node();
char buf[N];
scanf("%d", &n);
forn(i, n){
int t;
scanf("%d", &t);
if (t == 1){
scanf("%s", buf);
nm[i] = add_letter(0, buf[0] - 'a');
}
else{
int j;
scanf("%d%s", &j, buf);
--j;
nm[i] = add_letter(nm[j], buf[0] - 'a');
}
nms[nm[i]].push_back(i);
}
scanf("%d", &m);
forn(i, m){
int j;
scanf("%d%s", &j, buf);
--j;
reqs[j].push_back(i);
qr[i] = add_string(buf);
}
for (int v = 1; v < cntqr; ++v)
g[get_link(v)].push_back(v);
T = 0;
dfs_init(0);
dfs(0, 0);
forn(i, m)
printf("%d\n", ans[i]);
}
[DELETED]
In solution for C) editorial says that: If s[pos]=1 then we have to stay on the height 2, but in the sample test 1
8 2 5 00110010
It is optimal to go to height 1, after index 3, where s[3] = 1, and s[4] = 0 (as shown in the problem figure). What am I missing here?The "s" array in the editorial corresponds to intervals (so s[3] corresponds to the height of the interval (3, 4)), but the dp array "d" corresponds to the height at specific x-values.
In other words, because s[3] = 1, the road needs to be at height 2 at x=4, meaning that d[4][0] doesn't exist. s[4] = 0 instead means that d[5][0] and d[5][1] are both OK.
Огромное спасибо за решения! Каждый раз удивляюсь своему навыку всё усложнять ...
I didn't get the 2nd query of F ? What sum is supposed to calculate ?
sum of all those elements whose indices give remainder y when divided by x.
During contest, after solving first 5 problems, spent 1 hour working on problem F looking for a solution which was faster than O(n^(3/2)) because I assumed, incorrectly, that O(n^(3/2)) cannot pass... I even designed an O(n^(4/3)) algorithm to solve a simpler version of the problem where all the numbers are fixed from the beginning and never modified. (The solution is similar to the solution in the editorial except that the value of K is n^(2/3) instead of sqrt(n)). I then spent all the time trying to improve my algorithm to support modification to the sequence...
Honestly, I also felt that problem E was much easier than problem C and D.
I think 500000 is too large that my friend sxd666 got FST only because he used long long instead of int.
For queries with small x (x≤K), we may notice two things:
k=4 1 2 3 4 5 6 7 8 then 1 2 3 4 is only possible for <=k and each can have atmost ai-1 remainder, hence total approximately k^2 queries.
IN ques.D for counting of cnt1,given is cnt1=c1!*c2*!..cn! my doubt is while calculating c1! ,it is not necessary that the corrsponding elements in the another column will be all different and give different permutations..so we must divide it by those factorials..
Even if you consider the second column, even two sets of identical pairs will need to be considered twice so there is no need to divide.
I was thinking the same thing. The third sample case is as follows
The given answer is 4. However, there are only 3 ways to arrange the above pairs (3!/2!). What am I misunderstanding?
Permutations->
1,2,3
2,1,3.
So only two bad sequences. Hence 4 good sequences.
I thought 1,2,3 and 2,1,3 shouldn't be counted twice, since they are identical sequences, but the permutations are distinct, so they should be counted separately. Got it, thanks!
An online solution to problem G :
We build the suffix automaton for the trie which is given, and then we build a segment tree for every node (endpos set) . For a query, we do the heavy-chain decomposition for the trie, and then we query the segment tree sum.
Total time complexity is $$$\mathrm O(n\log^2n)$$$.
My code : https://mirror.codeforces.com/contest/1207/submission/59299826
This method use so much memory that it will get MLE on test 21 (https://mirror.codeforces.com/contest/1207/submission/59296517), but you can get AC by replacing the array with
std::map
.Sorry for my poor English.
Why your code links to submission by different user?
The editorial solution for C,
should it be
why the solution ignores the 0 to 1 transition when the s[i] == '1'?
When s[i] = '0', there are 4 possibilities, you can reach 'pos+1', that is two transitions each from height 1 and 2.
When s[i] = '1', there is only one 1 possibility, you can reach 'pos+1', that is using one gas pipeline and 2 pillars.
Pictorial illustration
but When s[i] = '1', why it can not be height 1 to height 2 transition? which uses 2 pipes and 2 pillar
Because you can only have zig-zagged line in the interval (i, i+1) when s[i] = '0', when s[i] = '1', you cannot break the line, it must be linear coming from the left side. Hence you can only modify dp[i+1][1].
ok, I got it. Thank you.
I am getting wrong Answer on Test 13 in Problem 1207C Gas Pipeline. My logic is that i am using dp[j][0] which is the cost to bring pipeline to height 1 at position j and dp[j][1] for cost to bring pipeline to height 2 at j. if Character at j is 1 dp[j][0] is -1 which means that it is impossible to bring pipeline to height 1. I am using MAX_VALUE in place of -1 in dp[j-1][0] if dp[j-1][0] is -1 which means it has a very high cost to build the pipeline from there.
Link to my Solution..
https://mirror.codeforces.com/contest/1207/submission/59357734
Can someone tell me why my submission is giving WA for question D. Thanks in advance
https://mirror.codeforces.com/contest/1207/submission/59385418
Here's the mistake. you are subtracting something from modded value. In some case value of tot will be less than (cnt1 + cnt2 — cnt12) or (cnt1 + cnt2) that's why your final answer is landing to negative value.
replace your lines with below lines.
Oh right Thanks a lot . After one hour of struggling it was the MOD :p
Hey, I understood the approach to calculate c1,c2. Can you elaborate on how to calculate c12.
It would be much helpful. Thank you :)
F is not worth 2100.
What do you mean? For each problem you get 1 point for solving it.
UPDATE: OK, I see. Tags with numbers of points have been added.
Could anyone give me a greedy solution for problem C. I came up with this approach in the contest but I can't implement it correctly. Thanks in advance!
https://mirror.codeforces.com/contest/1207/submission/59389852
thank u
https://mirror.codeforces.com/contest/1207/submission/59315647
In the editorial of Problem F it states that: "Note that, as in most problems related to sqrt-heuristics, it may be optimal to choose the constant that is not exactly sqrt(N), but something similar to it (but most solutions should pass without tuning the constant)"
Could anyone please explain why it may not be optimal to choose exactly sqrt(N)?
The two parts of the algorithm have O(K) and O(N/K) complexities but the constant factor will not necessarily be the same (e.g. we do a modulo and use more memory for the small x part and always update K elements, while the naive algorithm for large x just sums N/x values which is only at most N/K... many things to consider).
Pushing K on one side or the other of sqrt(N) will increase the time spent on one part and reduce the other, so because of the constant factors the optimal sum of complexities might be for 0.7sqrt(N) or 3.5sqrt(N) or whatever. Here sqrt(N) is 750 but experimentaly i got the lowest execution time with K around 400.
Do people really test this in competition though ? Or just guess and round a bit up or down ?
[deleted]
I've used greedy approach to solve problem C. It fails on test case 13. Please tell me where it goes wrong. Code
You have misread the problem like me:) : the problem says that you MUST start and finish the pipeline on height 1. So you don't need to take the case of the height of the pipeline being 2 for the initial zero subarray, and for the final zero subarray.
Please someone explain the problem E !!
I couldn't understand from the editorial.
1) In each query generate numbers in the way to check some bits in any $$$i$$$ case (if we are sure that $$$k_{th}$$$ bit is '1' in choosed number and '0' in answer, then $$$x$$$ has $$$k_{th}$$$ bit also '1', otherwise it is '0' — it follows from the properties of XOR).
2) Let's fix first $$$a$$$ bits as '1' and choose any combinations in another $$$14 - a$$$ bits. We have to generate $$$100$$$ different combinations, so $$$2^{14 - a}$$$ must be better than $$$100$$$ => $$$14 - a = 7, a = 7$$$ ($$$2^7 = 128 > 100$$$).
So we fix first $$$7$$$ bits as $$$1111111$$$ and increase another, getting the following sequence: $$$11111110000000_2$$$, $$$11111110000001_2$$$, $$$11111110000010_2$$$ and etc.
3) Using the same algorithm generate another $$$100$$$ numbers, but visa versa: $$$00000001111111_2$$$, $$$00000011111111_2$$$, $$$00000010111111_2$$$ and etc.
4) From first query answer we check first $$$7$$$ bits using XOR, from another query answer — last $$$7$$$ bits and finally get complete answer.
Oh so, now I get it. Thanks a lot !!
Task F is quite easy to solve and code, but statement is quite hard to understand :D
At first I thought that it is necessary to calculate the sum of all elements $$$a_i = k \cdot x + y$$$, not indexes)
In G instead of adding on path to the root and extracting value from vertex we can do: add to a vertex and calculate sum in a subtree (it can be easily verified to be equivalent)
Another solution for problem G:
There are no more than $$$S$$$ = $$$2 \times sqrt(4 \times 10^5)$$$ different lengths in the set of all patterns, say $$$L_1, L_2, ..., L_S$$$.
When DFS to some trie node $$$v$$$, among all different patterns with length $$$L_i$$$, there is at most one occurrence ending at node $$$v$$$.
Therefore, maintaining number of occurrences of all different patterns can be done in $$$O(S)$$$ whenever DFS moves to next vertex.
So you do an ordinary Aho-Corasick but with the text inside which we search being a trie rather than just a plain text?
I think we can even bound S by sqrt(2*4*10^5) but is it enough? Your total compexity is O(S*T). It can be as much as 350e6 operations. Have you checked if this solution passes the tests?
Sorry I forget to reply for a very long time. :P
Yes I did, right after the contest. Here is the link:
https://mirror.codeforces.com/contest/1207/submission/59360068
https://mirror.codeforces.com/contest/1207/submission/59322378
(I got two and now I don't know why!)
I think 350e6 is acceptable considering TL is 3 seconds.
Thanks anyway!
I get your meaning. But the total complexity is $$$S * totLen * O(hash)$$$, which is $$$4e8 * O(hash)$$$
I suspect it will get $$$TLE$$$ verdict though.
Did you implent the method you mentioned? I'm just curious.
Thank you
Well, I don't get why there is an $$$O(hash)$$$ in the complexity.
If I remember well, it's $$$O(S \times totLen)$$$. (Maybe I'm wrong because it's very long ago :P)
Here's the link of my implementation:
https://mirror.codeforces.com/contest/1207/submission/59360068 https://mirror.codeforces.com/contest/1207/submission/59322378
(I got two and now I don't know why.)
Oh, I get your method, thanks!!
Previoulsy, I thought you'll use hash to record the answer, but indeed you still use Aho-Corasick. Besides, your method is simplier than using a data structure to calculate the answer.
Can someone explain how to calculate c12 more elaborately in Div2D?
For E
I have an approach but don't know whether it's feasible or not.
Let us denote numbers of $$$1^{st}$$$ query by $$$a_i$$$ and numbers of $$$2^{nd}$$$ query by $$$b_j$$$.So if we select numbers in such a way that xor of any pair ($$$a_i$$$,$$$b_j$$$) is unique. Now let us denote the output to two queries by $$$N$$$ and $$$M$$$ respectively then we can say that $$$N$$$ = $$$a_i \oplus x$$$ and $$$M$$$ = $$$b_j \oplus x$$$.If we now do $$$N \oplus M$$$ then we get $$$a_i \oplus b_j$$$ .Since we selected such numbers that every pair has unique xor we know value of $$$a_i$$$ and $$$b_j$$$ and once we get this we can get $$$x$$$ by $$$N \oplus a_i$$$ or $$$M \oplus b_j$$$.
So my question is there any way to select such numbers that their xor is unique.BledDest
I have done it in a similar way. 219922345. The two array elements range till 1e5 at max when started with the Identity element in the first array.
Why am I getting runtime error in D? https://mirror.codeforces.com/contest/1207/submission/60137631
We can also solve E just by brute-force. lets say we gave two sequence (Ai,Bi) to the judge now it will return Ai^x and Bi^x ,take xor of these values we get Ai^Bi. If we can generate two lists of size 100 such Ai^Bi is distinct for every Ai,Bi. This can be done by brute force (have a look at my submission https://mirror.codeforces.com/contest/1207/submission/6769403) Now we know the Ai,Bi hence x will be just Ai^(Ai^x).
I tried to solve problem C greedily but got WA on test case 13
So please somebody tell me where i am wrong
Solution link : https://mirror.codeforces.com/contest/1207/submission/95326809
So many of us have got WA on test 13(including me) using the greedy approach for Problem C... Anyone figured out why that is the case? Update : found out myself.