Блог пользователя atcoder_official

Автор atcoder_official, история, 13 месяцев назад, По-английски

We will hold AtCoder Beginner Contest 423.

We are looking forward to your participation!

  • Проголосовать: нравится
  • +43
  • Проголосовать: не нравится

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Hope to have good grades and quality.(qp)

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +7 Проголосовать: не нравится

Notice that the point of problem A is abnormal, so I hope that this contest will not be a bad one. GL & HF!

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +11 Проголосовать: не нравится

all the best everyone! excited for this

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится -50 Проголосовать: не нравится

祝大家取得好成绩

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится -49 Проголосовать: не нравится

祝大家取得好成绩

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

Why Sunday again?

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

good luck everyone!

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

RP++

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

Missing one testcase in ABC C

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

I messed up, could not get one test case in C. could implement E but suprise suprise, no time left as I invested all of it in C

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

How to solve F?

  • »
    »
    13 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится +1 Проголосовать: не нравится

    typical inclusion-exclusion

    • »
      »
      »
      13 месяцев назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      Could you talk about it more detailed?

      • »
        »
        »
        »
        13 месяцев назад, скрыть # ^ |
         
        Проголосовать: нравится +25 Проголосовать: не нравится

        consider a subset $$$s$$$ of $$$A$$$, which contains exactly $$$M+k$$$ elements.

        let $$$\text{lcm}(s)$$$ means the least common multiple of these elements in $$$s$$$.

        if $$$k$$$ is odd, it gives $$$-\binom{M+k}{M}\times \lfloor\frac{Y}{\text{lcm}(s)}\rfloor$$$ contribution to the answer;

        otherwise, it gives $$$\binom{M+k}{M}\times \lfloor\frac{Y}{\text{lcm}(s)}\rfloor$$$ contribution to the answer.

  • »
    »
    13 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится +3 Проголосовать: не нравится

    Compute the subset's LCM (prune early if LCM > Y) using bitmask and maintain the sum of multiples <= Y by size of subset.

    Then; you can use inclusion-exclusion principle and counting to get the integers <= Y exactly having M elements in the subset (we already have sum of multiples by size).

    I hope this helps or you can also refer editorial.

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

In problem E, there is a solution with asymptotics O(q * max(a)) , where I just count for each segment with what coefficient the number ai will enter

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

really annoyed with problem C

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

Problem C is too hard!I used about 35 minutes to solve A,B,D,E,F.But more than 40 to solve C...

  • »
    »
    13 месяцев назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    I made an observation for C:

    0 L 1 L 2 U 3 L 4 L 5(R)
    

    let's say you start at room 5, and U represents unlocked doors and L represents locked doors. In order to ensure that all the doors are locked, an optimal strategy would be to

    1. leave all doors along the path to the first unlocked door from the left unlocked
    2. lock the first unlocked door from the left
    3. head back to R and lock all doors as you go.

    Using X to denote the current position,

    0 L 1 L 2 U 3(X) **U** 4 **U** 5(R)
    

    we performed the switching operation twice, before locking the last unlocked door,

    0 L 1 L 2 **L** 3(X) **U** 4 **U** 5(R)
    

    and locking all doors back to R

    0 L 1 L 2 **L** 3 **L** 4 **L** 5(R)
    

    If I lock any door before returning to R, then I will incur an additional cost of returning to R.

    So if we let

    • $$$x$$$ denote the count of initially LOCKED doors along the path to the first unlocked door from the left
    • $$$y$$$ denote the number of initially UNLOCKED doors along the path to the first unlocked door from the left

    The minimum number of operations for doors $$$[0, R-1]$$$ would be $$$2x + y$$$.

    We can obtain the full count if we repeat this algorithm iterating from the right.

    AC Link: https://atcoder.jp/contests/abc423/submissions/69316804

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

What's the expected TC in E? I did a $$$O(Q*100*log(N))$$$ solution but got TLE

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Problem C

#include<bits/stdc++.h>
#define all(x) x.begin(),x.end()
#define nl '\n'

typedef long long ll;
typedef long double ld;

using namespace std;

const ll M1 = 1000000007;
const ll M9 = 998244353;
const ll INF = (ll)1e18;

void solve()
{
    ll n,r; cin>>n>>r;
    vector<ll> a(n+1); a[0]=1;
    for(ll i=1;i<=n;i++) cin>>a[i];

    ll ans=0;
    ll f=-1,l=-1;
    for(ll i=0;i<=n;i++)
    {
        if(a[i]==0)
        {
            f=i;
            break;
        }
    }
    for(ll i=n;i>=0;i--)
    {
        if(a[i]==0)
        {
            l=i;
            break;
        }
    }
    if(f==-1 && l==-1)
    {
        cout<<0<<nl;
        return;
    }
    for(ll i=f;i<=r;i++)
    {
        if(a[i]==0) ans++;
        else
        {
            if(i!=0 && i!=n)
            ans+=2;
        }
    }
    for(ll i=r+1;i<=l;i++)
    {
        if(a[i]==0) ans++;
        else
        {
            if(i!=0 && i!=n)
            ans+=2;
        }
    }

    cout<<ans<<nl;

}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    ll tc = 1;
    while (tc--)
    {
        solve();
    }
    return 0;
}

My code is failing only for a single testcase can anyone help me find the error in my code.

  • »
    »
    13 месяцев назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    why do you use the


    if(i!=0 && i!=n) ans+=2

    ? I think you should add 2 to ans regardless of the condition. as long as it is in between f and l and is a locked door, you need to unlock it and lock it again

    • »
      »
      »
      13 месяцев назад, скрыть # ^ |
      ← Rev. 3  
      Проголосовать: нравится 0 Проголосовать: не нравится

      Actually, the condition is not the cause.

      I think the question says the starting room is R, and you can only access the R-1 and Rth door at first. However your for loop is trying to access the R and R+1th door first

      it is very subtle to realize this, but the problem statement is intentionally designed to trick you into think you can access the R and R+1 door first, but according to the statement, the distribution of room and door is like this:

      R0 D1 R1 D2 R2 D3 R3 D4...

      if you start with the 1st room R1, then you can access the 1st and 2nd door, but the index of the door accessing is actually 0 and 1.

  • »
    »
    13 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    [hack input] 6 6 1 0 0 0 0 1 [hack answer] 6 [your output] 4

    you should wrote if(i!=0) instead of if(i!=0 && i!=n) because there's no door at 0 but there IS a door at n.

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

for C, go to either direction from R if there is at least one 0 in that direction, all the obstructing (locked) doors in the way need to be unlocked before you get to the farthest 0. Once you get to that 0, greedily lock all the doors.

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

Sadly, I have a E's solution with Mo's in last 20min, but I have no time to finish it :(

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Questions E and F remain highly formulaic, with the sole merit being that Question G offers some insight.

»
13 месяцев назад, скрыть # |
← Rev. 3  
Проголосовать: нравится -11 Проголосовать: не нравится

a great contest! but maybe the problem F can be a little more difficult. (upd: I apologize for my previous awkward English expression. It was not my intention to offend anyone. In my previous statement, ABC only stands for Atcoder Beginner's Contest and has no other meanings.)

»
13 месяцев назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

can anyone share the concept for solving E?

  • »
    »
    13 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    I used mo's algorithm.

  • »
    »
    13 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится +1 Проголосовать: не нравится

    Replace array $$$a$$$ with prefix sum array $$$p$$$ of length $$$n + 1$$$, $$$p_i$$$ = sum of $$$i$$$ first elements.

    Then we want to calculate the sum $$$p_{r+1} - p_l$$$ for all pairs $$$(l, r)$$$ such that $$$L \le l \le r \e R$$$. Let's replace $$$r$$$ with $$$r+1$$$ and get $$$p_r - p_l$$$ for $$$L \le l \lt r \le R + 1$$$.

    Let's look at contribution of the term $$$p_i$$$. There are $$$i - L$$$ elements to the left of $$$i$$$, so that will add $$$p_i (i - L)$$$. Also there are $$$R + 1 - i$$$ elements to the right of $$$i$$$, that will subtract $$$(R - i + 1) p_i$$$. So, we want to find the sum of $$$p_i (i - L - R - 1 + i) = p_i (2i - L - R - 1)$$$ for all $$$L \le i \le R + 1$$$.

    By calculating prefix sums of $$$p_i$$$ and $$$p_i \times i$$$ we can find the answer in $$$O(1)$$$.

    P. S.: somewhere in the calculations I messed up with +- 1, because on the contest I just tried some variations until it worked out

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

Nice solution for E using the contribution technique.

For a fixed value $$$v$$$, suppose an occurrence of $$$v$$$ is at position $$$k$$$ and we consider subarray $$$[L, R]$$$.
The number of subarrays $$$[L', R']$$$ with $$$L \leq L' \leq k \leq R' \leq R$$$ that include this occurrence equals

$$$ (k - (L-1)) \cdot ((R+1) - k). $$$

Expanding and simplifying gives

$$$ (k - (L-1))((R+1)-k) = k(R+1) - k^2 - (L-1)(R+1) + (L-1)k = k(R+L) - k^2 - (L-1)(R+1). $$$

So for all occurrences $$$k$$$ of value $$$v$$$ inside $$$[L, R]$$$, the total contribution (multiplied by $$$v$$$) is

$$$ v \cdot \Big( (R+L)\sum k - \sum k^2 - \text{cnt}\cdot (L-1)(R+1) \Big), $$$

where

  • $$$\sum k$$$ is the sum of indices of positions containing $$$v$$$ in $$$[L, R]$$$,
  • $$$\sum k^2$$$ is the sum of squared indices, and
  • $$$\text{cnt}$$$ is the count of $$$v$$$ in $$$[L, R]$$$.

Then each query $$$[L, R]$$$ uses $$$O(100)$$$ work (iterate over values).

Code
»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится -8 Проголосовать: не нравится

Can someone help me in question E? I know it's purely about mathematical manipulation and simplifying the expression. I did the same and the final expression I got is:

For any query (l, r): sum form l to r of : [ A_i * (i+1-l) * (r+1-i)] = -(S2) + (r+l)*S1 + (r+1)*(1-l)*S0

where S0 = sum form l to r of : A_i S1 = sum form l to r of : i*A_i S2 = sum form l to r of : i^2*A_i

Here's my code:

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

int main()
{
    int n, q;
    cin >> n >> q;
    vector<long long> a(n+1);
    a[0] = 0;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i+1];
    }

    vector<long long> pre_ai(n+1), pre_ai2(n+1);
    for (int i = 1; i <= n; i++)
    {
        pre_ai[i] = a[i]*i;
        // pre_ai[i] = a[i];
        // pre_ai2[i] = a[i]*(1-i*i);
        pre_ai2[i] = a[i]*(i*i);
    }


    
    for (int i = 2; i <= n; i++)
    {
        pre_ai2[i] += pre_ai2[i-1];
        a[i] += a[i-1];
        pre_ai[i] += pre_ai[i-1];
    }
    
    for (int i = 0; i < q; i++)
    {
        int l, r;
        cin >> l >> r;

        long long S0 = a[r] - a[l-1];
        long long S1 = pre_ai[r] - pre_ai[l-1];
        long long S2 = pre_ai2[r] - pre_ai2[l-1];

        long long ans = -S2 + (r+l)*S1 + (r+1)*(1-l)*S0;
        
        cout << ans << endl;
    }    
}

»
13 месяцев назад, скрыть # |
 
Проголосовать: нравится -8 Проголосовать: не нравится
Your code here...
// best tempplate
#include<bits/stdc++.h>
using namespace std;
#define int long long 

void solve(){
    int n, start;
    cin>>n>>start;
    vector<int>v(n);
    int left(-1), right(-1);
    for(int i=0;i<n;i++){
        cin>>v[i];
        if(left==-1 && v[i]==0) {
            left=i;
        }
        if(v[i]==0) right=i;   
    }
    vector<int> duplicate(v);
    if(left==-1 and right==-1){
        cout<<"0\n";
        return;
    }
    // left is leftmost index where v[i]===0 and right is rightmost index where v[i]===0
    start--; 
    int cost(0);
    if(start >=left and start<=right){
        //go left 
        //now till l from start everything is opened 
        for(int i=start;i>=left;i--){
            if(v[i]==1){
                cost++;
                v[i]=0;
            }
        }

        for(int i=left;i<=right;i++){
            if(v[i]==0){
                cost++;
            }
            if(v[i]==1){
                cost+=2;
            }
        }

      cout<<cost<<"\n";
        return ;
    }

    if(start < left){
        //go right 
        for(int i=start;i<=right;i++){
            // if(v[i]==0){
            //     cost++;
            // }
            if(v[i]==1){
                cost+=2;
            }
        }
        cout<<cost<<"\n";
        return ;
    }
    if(start > right){
        for(int i=start;i>=left;i--){
             if (v[i]==1){
                cost+=2;
            }
        }

        cout<<cost<<'\n';
        return ;
    }






    
}
signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
  solve();
    return 0;
}



please give why this solution to question c fails - i have tried my best after 15+ wrong submission please anybody clarify me what is wrong with my solution ONNLY 2 test cases getting WA

  • »
    »
    13 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    You have made two mistakes.

    1. You should keep if (v[i] == 0) cost++;, or you will fail on [hack input]
    6 6
    1 0 0 0 0 1
    

    [hack output]

    6
    
    1. You mistook up doors and rooms. Your left and right are id of doors while start is the id of room. Your for loop in the case start < left should start with i = start + 1, representing the door to the right of room start. Here's the hack for the second mistake

    [hack input]

    6 3
    1 1 1 0 1 1
    

    [hack output]

    1
    

    Generally, you should reduce classifications. You can view my code. I merged the three classes into one. That makes it less possible to make mistakes.