atcoder_official's blog

By atcoder_official, history, 7 months ago, In English

We will hold AtCoder Beginner Contest 356.

We are looking forward to your participation!

  • Vote: I like it
  • +102
  • Vote: I do not like it

»
7 months ago, # |
  Vote: I like it -32 Vote: I do not like it

vERY gOOd AtcodeR,making mY cOdE SpIn.

»
7 months ago, # |
  Vote: I like it -70 Vote: I do not like it

有中国人吗?

  • »
    »
    7 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Yes, but please communicate in English(请使用英语对话).

  • »
    »
    7 months ago, # ^ |
      Vote: I like it -13 Vote: I do not like it

    当然有 but,please speak Enlish and I don't know why we should speak Enlish

    • »
      »
      »
      7 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Because it is easy to understand and learn :)

  • »
    »
    7 months ago, # ^ |
      Vote: I like it -7 Vote: I do not like it

    • »
      »
      »
      7 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Please communicate in English.I'm sorry to vote down it.

  • »
    »
    7 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    How to change my name?

    • »
      »
      »
      6 months ago, # ^ |
      Rev. 3   Vote: I like it 0 Vote: I do not like it

      You can only change your name once in the end of a year.

      UPD:I forget that you can change your name infinitely in at most 7 days after you registered a new account.

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

is this hard?

  • »
    »
    7 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Yes.

    • »
      »
      »
      7 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      i can only answer the first problem, lol. i'm stuck at the 2nd and the 3rd one. is the 2nd problem use dynamic programming?

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Please discuss after contest

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        I can answer the first and the second problems.But I have no time to answer the third problem.

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        I know the first, second, third, fourth, and fifth questions. The competition has ended, and I definitely have time to answer them for you, but I'm going to sleep. You can check my submission records. My name is Littlesnake, and I wish you good luck, buddy.

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        second:

        # include <bits/stdc++.h>
        
        using namespace std;
        
        int n, m, X[110][110], A[110], B[110];
        
        int main () {
        
        	cin >> n >> m;
        	for (int i = 1; i <= m; i ++) cin >> A[i];
        	for (int i = 1; i <= n; i ++) {
        		for (int j = 1; j <= m; j ++) {
        			cin >> X[i][j];
        			B[j] += X[i][j];
        		}
        	}
        	for (int i = 1; i <= m; i ++) {
        		if (B[i] < A[i]) {
        			cout << "No";
        			return 0;
        		}
        	}
        	cout << "Yes";
        
        	return 0;
        }
        
        
»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

You are right. But G is only 575 pts?

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Hope everyone to have fun! And I hope a positive delta.I've already got negative deltas for a long time(only 4 probs)...

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Hope for a funny and relaxing contest on International Children's Day.

  • »
    »
    7 months ago, # ^ |
      Vote: I like it -12 Vote: I do not like it

    International Children's Day is on November 20th to commemorate the Declaration of the Rights of the Child by the United National General Assembly on November 20th, 1959.

    June 1st is celebrated as Children's Day primarily in communist and post-communist countries. The date was arbitrarily selected by the Women's International Democratic Federation in Moscow on November 4th, 1949.

    The United Nations has more authority in setting up international holidays.

»
7 months ago, # |
  Vote: I like it -8 Vote: I do not like it

Happy Children's Day!

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Good luck.

»
7 months ago, # |
  Vote: I like it -8 Vote: I do not like it

Happy Children's day!

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Interesting problems, this was a bit tougher than 355. My second ABC and it feels so much more diverse and balanced than recent CF rounds, great job.

Sadly rounding down in E ruins such a beautiful solution:

for a in aa {
    sum -= a;
    ans += sum / a;
}

Couldn't find fix for it.

»
7 months ago, # |
  Vote: I like it +3 Vote: I do not like it

Why O(max(a) * log(max(a))) gives TLE in E?

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Whats the mistake in my code for problem-C ? Code

  • »
    »
    7 months ago, # ^ |
    Rev. 5   Vote: I like it 0 Vote: I do not like it

    I think the problem is the logic you use to check if a key configuration is valid or not. For example, if popcount(i) < k you never increase ans. But consider for example the test case

    1 1 1

    1 1 x

    i = 0 is a valid configuration here but popcount(i) < k.

    • »
      »
      »
      7 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      ya i just removed the condition popcount(i) >= k.

      Thank you

»
7 months ago, # |
  Vote: I like it +29 Vote: I do not like it

Why is today's G only worth 575 points? I think it is as hard as last round's G, which is 650 points. (and the statistics agrees with me too!)

  • »
    »
    7 months ago, # ^ |
      Vote: I like it -15 Vote: I do not like it

    AtCoder Beginner Contests always have one too few testers for an accurate difficulty perception.

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

What's the matter with my segment tree algorithm on problem E?

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
pair<long long,long long>b[200010];
long long n,a[200010],tree1[800010],tree2[800010],lazy[800010];
map<pair<long long,long long>,long long>id;
void change1(long long now,long long l,long long r,long long x,long long k)
{
	if(r<x||l>x) return;
	if(l==r)
	{
		tree1[now]=k;
		return;
	}
	long long mid=(l+r)>>1;
	if(x<=mid) change1(now<<1,l,mid,x,k);
	else change1(now<<1|1,mid+1,r,x,k);
	tree1[now]=tree1[now<<1]+tree1[now<<1|1];
}
long long find1(long long now,long long l,long long r,long long x,long long y)
{
	if(r<x||l>y) return 0;
	if(x<=l&&r<=y) return tree1[now];
	long long mid=(l+r)>>1,res=0;
	if(x<=mid) res+=find1(now<<1,l,mid,x,y);
	if(y>mid) res+=find1(now<<1|1,mid+1,r,x,y);
	return res;
}
void push_down(long long now,long long l,long long r)
{
	long long mid=(l+r)>>1;
	lazy[now<<1]=lazy[now];
	lazy[now<<1|1]=lazy[now];
	tree2[now<<1]+=lazy[now]*(mid-l+1);
	tree2[now<<1|1]+=lazy[now]*(r-mid);
	lazy[now]=0;
}
void change2(long long now,long long l,long long r,long long x,long long y,long long k)
{
	if(r<x||l>y) return;
	if(x<=l&&r<=y)
	{
		lazy[now]=k;
		tree2[now]+=k*(r-l+1);
		return;
	}
	push_down(now,l,r);
	long long mid=(l+r)>>1;
	if(x<=mid) change2(now<<1,l,mid,x,y,k);
	if(y>mid) change2(now<<1|1,mid+1,r,x,y,k);
	tree2[now]=tree2[now<<1]+tree2[now<<1|1];
}
long long find2(long long now,long long l,long long r,long long x,long long y)
{
	if(r<x||l>y) return 0;
	if(x<=l&&r<=y) return tree2[now];
	push_down(now,l,r);
	long long mid=(l+r)>>1,res=0;
	if(x<=mid) res+=find2(now<<1,l,mid,x,y);
	if(y>mid) res+=find2(now<<1|1,mid+1,r,x,y);
	return res;
}
int main()
{
	scanf("%lld",&n);
	for(long long i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		b[i].first=a[i];
		b[i].second=i;
	}
	stable_sort(b+1,b+n+1);
	for(long long i=1;i<=n;i++) id[b[i]]=i;
	long long ans=0;
	for(long long i=1;i<=n;i++)
	{
		long long tmp=id[make_pair(a[i],i)];
		long long tmp2=find1(1,1,n,tmp+1,n);
		ans+=tmp2/a[i];
		change1(1,1,n,tmp,1);
		change2(1,1,n,1,tmp-1,a[i]);
	}
	for(long long i=1;i<=n;i++)
	{
		long long tmp=find2(1,1,n,1,i-1);
		if(tmp==0) continue;
		ans+=tmp/b[i].first;
	}
	printf("%lld\n",ans);
}

It can't even AC any of the examples.

»
7 months ago, # |
Rev. 2   Vote: I like it +1 Vote: I do not like it

Can someone explain why my logics for C & D fail?

For C, I iterate over each possible subset and check if it does not contradict with the tests.

Spoiler

For D, I iterate over 1's in M, and count the number of 1's on i's position through k: 0->N. The counting can be done in O(1) since on i's position 0's and 1's are alternating like this: 01010101 (for bit 0) 00110011 (for bit 1) 00001111 (for bit 2) ...

Spoiler
  • »
    »
    7 months ago, # ^ |
      Vote: I like it +1 Vote: I do not like it

    For C, your code does not consider the possibility that there are no real keys (I made the same mistake). Consider this test case:

    1 1 1
    1 1 x
    

    The answer is 1 but your code gives 0.

    For D, I think there is an off by one error somewhere when you are calculating add. Consider this test case:

    4 4
    

    The answer is 1 but your code gives 0.

    • »
      »
      »
      7 months ago, # ^ |
        Vote: I like it +1 Vote: I do not like it

      Oh yes you’re right. Thank you, both problems passed now.

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

for E : How to find the remainder of the values which are greater than a[i] for every a[i] efficiently.

  • »
    »
    7 months ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    I don't think you can

    So ideas along the lines of $$$\lfloor\frac{a}{b}\rfloor = \frac{a-a\%b}{b}$$$ don't work because it's hard to calculate the sum of $$$a\%b$$$ quickly

  • »
    »
    6 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Here is an idea with the complexity of $$$O(\sum \limits_{i = 1}^n (a_i \sqrt{a_i}))$$$:

    You should remember these two theorems:

    1. For a fixed integer $$$n$$$, there is at most $$$O(\sqrt{n})$$$ different values of $$$\lfloor \frac{n}{i} \rfloor$$$.

    2. For a fixed integer $$$n$$$, assume $$$l$$$ is the minimum value of $$$i$$$ such that $$$\lfloor \frac{n}{i} \rfloor = x$$$, then the maximum value of $$$i$$$ satisfies the condition is $$$\lfloor \frac{n}{\lfloor \frac{n}{l} \rfloor} \rfloor$$$.

    Then pre-calculate the times of occurences of each value, then use these theorems to create a simple method:

    For each time, get an interval $$$[l, r]$$$ such that $$$\frac{n}{l} = \frac{n}{l + 1} = \cdots = \frac{n}{r}$$$, calculate the answer in $$$[l, r]$$$(it is easy), until $$$l > n$$$ where $$$n$$$ is the current value.

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Problem F can be solved by dividing into sqrt(Q) blocks of queries :D, I love sqrt decomposition.

  • »
    »
    7 months ago, # ^ |
      Vote: I like it +3 Vote: I do not like it

    Or by love with multiple sets

    Assume current set is $$$[1, 5, 10, 14, 19]$$$ and $$$K = 4$$$. Let's look at segments between each two consecutive elements: $$$[[1, 5], [5, 10], [10, 14], [14, 19]]$$$. Now lets leave only those, whose length is greater than $$$K$$$ and take only left points out of two: $$$[5, 14]$$$.

    Assume, the query is $$$1$$$. We apply lower_bound to this set and get $$$14$$$. This is the right point in connected component, that we are looking for. Now use indexed_set to find its number in original set.

    To find left point in connected component use another set (Why C++ doesn't have xxx_bound to left direction...).

    • »
      »
      »
      7 months ago, # ^ |
      Rev. 2   Vote: I like it +3 Vote: I do not like it

      I don't actually use indexed_set anymore as it won't help me a lot in offline contests (I can't use the extension library) but thanks for another way to solve the problem! I've also thought about getting the index first but I forgot about indexed sets hehe :D

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it +3 Vote: I do not like it

        Actually, I think it is a good idea to learn just this magic line, as it helps me quite often. I guess, the only another way to do it is by implementing cartesian tree by hands, which is far worse idea for offline contest.

        typedef tree<int,null_type,less<int>,rb_tree_tag, tree_order_statistics_node_update> indexed_set;
        
        • »
          »
          »
          »
          »
          7 months ago, # ^ |
            Vote: I like it +3 Vote: I do not like it

          the problem is that our offline judge (known as Themis) doesn't support extended libraries so maybe (just maybe) I can instead use a trie to store

    • »
      »
      »
      7 months ago, # ^ |
      Rev. 2   Vote: I like it +3 Vote: I do not like it

      I did something similar, but with 4 sets (set of current points, ordered_set of current points, set of points whose closest point on the left is at a distance > K, set of points whose closest point on the right is at a distance > K). Here's the submission. Tbh I was surprised by the low solve count.

      Sadly, I entered contest 1 hour after the start and missed out on +100 delta :(.

  • »
    »
    7 months ago, # ^ |
      Vote: I like it +3 Vote: I do not like it

    Mo's algo and DSU, the one in the EDU section?

»
7 months ago, # |
  Vote: I like it +3 Vote: I do not like it

why range based segment tree won't work for Problem F ?


#include <bits/stdc++.h> #define int long long using namespace std; struct Bird { int Value; // Minimum value of a segment Bird *LeftChild, *RightChild; // Pointers to left child and right child Bird() // Constructor { Value = 0; LeftChild = NULL; RightChild = NULL; } void BirdLay() // Construct Childs { if (LeftChild == NULL) LeftChild = new Bird(); if (RightChild == NULL) RightChild = new Bird(); } }; Bird* Root = new Bird(); // The first Node that manage [1, N] Bird* Root1 = new Bird(); // The first Node that manage [1, N] void BirdPerch(Bird *Current, int curL, int curR, int Pos, int newValue) { if (curL > Pos || curR < Pos) { // Pos is not in range [curL, curR] return; } if (curL == curR) { // Current is the Node that manage only Posth element Current -> Value = newValue; return; } int mid = (curL + curR) / 2; Current -> BirdLay(); BirdPerch(Current -> LeftChild, curL, mid, Pos, newValue); BirdPerch(Current -> RightChild, mid + 1, curR, Pos, newValue); Current -> Value = (Current -> LeftChild -> Value + Current -> RightChild -> Value); } int BirdFly(Bird *Current, int curL, int curR, int L, int R) { if (curL > R || curR < L) { // [curL, curR] doesn't intersect with [L, R] return 0; } if (L <= curL && curR <= R) { // [curL, curR] is inside [L, R] return Current -> Value; } int mid = (curL + curR) / 2; Current -> BirdLay(); return (BirdFly(Current -> LeftChild, curL, mid, L, R) + BirdFly(Current -> RightChild, mid + 1, curR, L, R)); } int32_t main() { ios_base::sync_with_stdio(false); cin.tie(0); int N, Q; cin >> N; int q; int k; cin>>k; Q = N; char Type; int Pos, newValue, L, R; int mt = 1e16; for(int i = 0; i < N; i++){ int t; cin>>t; if(t == 1){ int x; cin>>x; int s = BirdFly(Root1, 1, mt, x, x); if(s == 1){ // if already there delete it //cout<<x<<endl; BirdPerch(Root1, 1, mt, x, -1); } else { BirdPerch(Root1, 1, mt, x, 1); } } else { int x; cin>>x; int s = BirdFly(Root1, 1, mt, max(1ll*0, x - k), x + k); cout<<s<<endl; } } //cout<<res<<endl; }
»
7 months ago, # |
Rev. 3   Vote: I like it +9 Vote: I do not like it

Problem setter, I don't know who you are, but I love you, you are amazing! =)

I laughed so hard when I solved problem C and read the problem statement of D =))))

Problem A is very ez, but was so satisfying to solve with clean c++ std. Pure joy =))

Problem A
»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

How to solve problem E. The editorial is too complex for me.

  • »
    »
    7 months ago, # ^ |
      Vote: I like it +7 Vote: I do not like it

    At first assume, that there are no repeating numbers.

    First let's sort the array. Assume, we have following: $$$[1, 2, 4, 5]$$$. We are calculating following: $$$(2 / 1 + 4 / 1 + 5 / 1) + (4 / 2 + 5 / 2) + (5 / 4)$$$. Let's calculate it parenthesis by parenthesis.

    Assume, current number is $$$x$$$. By dividing which numbers by $$$x$$$ we get $$$1$$$? Numbers $$$x, x+1, \dots, 2x - 1$$$. By dividing which numbers by $$$x$$$ we get $$$y$$$? Numbers $$$xy, xy + 1, \dots, (x+1)y - 1$$$. Let's instead of original array use array of occurences: $$$[1, 1, 0, 1, 1, 0, 0, 0, \dots]$$$, which means, there is one occurence of $$$1$$$, one occurence of $$$2$$$, zero occurences of $$$3$$$, etc. Let's build prefix sums $$$ps$$$ on this array. Now the required number is $$$ps[(x + 1)y] - ps[xy]$$$.

    We need to iterate over all possible $$$y$$$. But aren't there too many of them? We don't need to have $$$xy > 10^6 = C$$$, because there will be only zeros in array of occurences. So $$$y \le \frac{C}{x}$$$. Number of iterations will be $$$\frac{C}{1} + \frac{C}{2} + \frac{C}{3} + \dots + \frac{C}{C} = C(\frac{1}{1} + \frac{1}{2} + \frac{1}{3} + \dots + \frac{1}{C})$$$. The expression in parenthesis is well-known. It is called harmonic series and is approximately equal to $$$\ln(C)$$$. So if we simply iterate over all $$$x$$$ and $$$y$$$ up to $$$\frac{C}{x}$$$ it will be $$$C \cdot \ln(C)$$$ time.

    About repeating number. In straightforward implementation all pairs of repeated numbers will be calculated, but we need to calculate them left to right direction. To do it, we can simply subtract all extra pairs by $$$res -= \frac{cnt(cnt + 1)}{2}$$$.

    • »
      »
      »
      7 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      I was thinking on sorting numbers in descending order and then for each number calculate how many numbers are in range >= x & < 2x, >= 2x & <3 x, .....

      I was thinking to do this by binary search. Can it be done better?

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it +3 Vote: I do not like it

        We can leave the original sorted array. For each number $$$x$$$ in the array iterate on all $$$y$$$ and find corresponding segment $$$[xy, (x+y)y - 1]$$$ by binary search.

        But we also need to not iterate on same value $$$x$$$ several times, if it has several occurences. We need to do it once and then multiply by the number of occurences and also add the binomial coefficient of number of ordered pairs of these repeated elements.

        It is $$$C \cdot \ln(C) \cdot \log(n)$$$ and looks harder to implement.

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Yes, create an array that holds the count of each number, and you can easily calculate the count of numbers between a and b using prefix sums.

    • »
      »
      »
      7 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Could you help me understand how sorting does not change the answer say our array is [2 10 10 10 1] then 2/1 pair will never come but in sorted array it does appear

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Did you understand why the order of the array doesn't matter?

      • »
        »
        »
        »
        7 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        but in sorted array 1,2 will come which will have the same max and min.

»
7 months ago, # |
Rev. 4   Vote: I like it 0 Vote: I do not like it

MySolution Can anyone please tell me what is wrong in my solution for C — Keys? ;)

  • »
    »
    7 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    A lot of people (including me) are making the same mistake for C, consider this test case:

    1 1 1
    1 1 x
    

    The answer is 1 but your code gives 0.

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it
»
7 months ago, # |
Rev. 2   Vote: I like it +3 Vote: I do not like it

In F, I used DCP offline on unordered_maps

Code
Explanation
»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Atcoder should have a NO AI TEST

  • »
    »
    7 months ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    If you take a look at the fastest submissions of A,C,D,you'll find that they are apparently written by AI.By the way,this and this didn't delete the comment "Generated by OpenAI gpt-4o".(Laugh)

»
7 months ago, # |
Rev. 2   Vote: I like it +8 Vote: I do not like it

F using binary search and segment tree. For a x, we need to know the leftmost element having absolute different with element to it's left > k. In the same way we will find the rightmost element having absolute different with element to it's right > k. Now we have 2 indexes a and b. The answer will be no of element in the range [a, b] which are still part of S. Sorry for my bad English.

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

for e may someone tell me what is matter of my code?

#include <iostream>

using namespace std;

const int N = 1e6 + 10;

typedef long long LL;
int a[N], cnt[N];
LL s[N];

int main() {
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++ ) {
        cin >> a[i];
        cnt[a[i]] ++;
    }
    // x --- 2x - 1 --> 1; 2x --- 3x - 1 --> 2
    for(int i = 1; i <= 1000000; i ++ ) s[i] = s[i - 1] + cnt[i];
    LL ans = 0;
    for(int i = 1; i <= 1000000; i ++ ) {
        if(!cnt[i]) continue;
        for(int j = i; j <= 1000000; j += i) {
            int r = min(j + i - 1, 1000000);
            ans += (long long)cnt[i] * (s[r] - s[j - 1]) * (r / i);
        }
        if(cnt[i] > 1) {
            ans -= cnt[i];
            ans += ((long long)cnt[i] * cnt[i] - 1) / 2;
        }
    }
    cout << ans - n;
    return 0;
}
»
7 months ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

In problem C, the following solution of mine got AC. I thought it would be a TLE. What I did is calculate for every combination using bitmask. In worse case it is O((2^N)*M*N)=O((2^15)*100*15)=49,152,000. Can someone please explain why is it not TLE?

my solution

  • »
    »
    7 months ago, # ^ |
    Rev. 3   Vote: I like it 0 Vote: I do not like it

    $$$O(m2^n)+O(mn)$$$ solutions run in 1..5ms, yours is 45 so it seems quite consistent

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

a complete beginner here, where would one rate the difficulty of this challenge? This was my first CC at I could only crack the first two.

»
7 months ago, # |
  Vote: I like it 0 Vote: I do not like it

https://atcoder.jp/contests/abc356/submissions/54163403

Any idea why a simple functional implementation would give wrong answer rather than tle?

»
6 months ago, # |
  Vote: I like it 0 Vote: I do not like it

Where can one find the complete set of test cases for problem E for this contest?