2

So I was working out a codeforces problem and found this out...

#include <iostream>

int main()
{
    long long var = 1e17;
    long long mod = 998244353;
    std::cout << var % mod;
}

The output was:

470904831

which is actually not the right answer. The correct answer is:

470904832

Actually, in the problem, it was with loops using principles of modulo operator of multiplication and addition, but this is one of the examples where it failed.

If somebody can tell me what is going on, then it would be of great help.

Edit: I might have some misunderstanding, I compared the result with an online modulo calculator and it disagrees with the code... So, have a look at my code to the problem itself.

Link to the question:here.

The thing which I did in below code is as follows,

We notice that in f(ai,aj)=k can be written as follows,

suppose ai=12 and aj=34, k=1020 + 304=1324.

I call 1020 as "left shift" as the zero is appended from right and the number is shifted left.

Similarly 304 is called "right shift" and every number is added into the final result in both the forms and both the forms are occurring "n" times.

At the end, We just have to add those and return their modulo.

Till here, If there is any error in my working then please do tell.

Below is the implimentation,(Please don't be harsh on my ways of doing things, I am learning and if you can do it in few less lines then please don't judge)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    //--<for debugging>
    #define whatis(x) cout << #x << " is " << x<<" ";
    #define whatisl(x) cout << #x << " is " << x<<"\n";
    #define parr(array,end)for(ll loop=0;loop<end;loop++)cout<<array[loop]<<" ";cout<<"\n";
    #define lline cout<<"\n";
    #define errorl(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args);cout<<"\n";}
    #define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args);cout<<"___";}
        
    void err(istream_iterator<string> it) {}
    template<typename T, typename... Args>
    void err(istream_iterator<string> it, T a, Args... args) {
        cout << *it << " = " << a <<" , ";
        err(++it, args...);
    }
    //--</for debugging> 
    #define rep(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
    #define testcase ll tt; cin >> tt; while(tt--)
    #define boost ios_base::sync_with_stdio(false);cin.tie(NULL);
    #define pb push_back 
    #define vars ll h,i,j,k,d,l,p,q,r,x,y,a,b,c,v,var,n,m,z,s,ans,ind1,ind2,flag,limit1,limit2,limit3,mod;
    #define vll vector<ll>
    #define pll pair<ll,ll>
    #define sll set<ll>
    #define pint pair<int,int>
    const ll INF=1e9+7;
    const ll MOD=998244353;
    int main()
    {
        boost vars
        cin>>n;
        ll arr[n];
        for(i=0;i<n;i++)cin>>arr[i];
        ans=0;
        for(i=0;i<n;i++)
        {
            v=arr[i];
            s=0;
            p=10;
            //left shift
            while(v)
            {
                z=v%10;
                v/=10;
                s=(s+(p*z)%MOD)%MOD;
                p=(p*100)%MOD;
                //errorl(p);
            }
            error(s);
            a=(s*n)%MOD;s=0;v=arr[i];p=1;
            // right shift
            while(v)
            {
                z=v%10;
                v/=10;
                s=(s+(p*z)%MOD)%MOD;
                p=(p*100)%MOD;
            }
            b=(s*n)%MOD;
            ans+=(a+b)%MOD;
            errorl(s,a,b,ans);
        }
        cout<<ans;
    }

The code gave wrong answer when Input =

5

1000000000 1000000000 1000000000 1000000000 1000000000

The correct answer is

265359409

My code gave answer =

2261848115

I highly appreciate your effort honestly, I didn't think that so many people will reply to this.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Why did you include a non-standard "bits/" header? – einpoklum May 26 '20 at 14:35
  • Print the value of `var`. Most likely it is off by one due to floating point inaccuracies: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – NathanOliver May 26 '20 at 14:35
  • 6
    how did you get your "correct" answer? See [here](https://www.wolframalpha.com/input/?i=mod%281e17%2C+998244353%29) – 463035818_is_not_an_ai May 26 '20 at 14:35
  • `var=1e17` is floating point to `long long` conversion. – Richard Critten May 26 '20 at 14:38
  • @RichardCritten but it is not reason for error –  May 26 '20 at 15:34
  • This link for the modulo calculator which I used was this:[here](https://goodcalculators.com/modulo-calculator/) – martin rose May 26 '20 at 21:33
  • I'm afraid I have calculated that modulus by three different methods and it gives the correct answer (by those three different methods) as the one you mark as incorrect (`470904831`) You have a problem with your `1E17` which is not a `long long` but a `double` (with about 17 significative digits) so you are in the limit of beginning to lose precission due to lack of bits in the significand. – Luis Colorado May 27 '20 at 14:51
  • Can you describe how have you calculated the _correct_ answer? – Luis Colorado May 27 '20 at 15:31
  • @LuisColorado as mentioned in the post, I had a misunderstanding, and the site from which I calculated the modulo was **also** giving incorrect answers. The code produced the correct result. So the only thing is to find the bug in the code for the problem itself – martin rose May 27 '20 at 16:40
  • @martinrose, but the code is giving the correct answer. The remainder you say your code is outputting is correct. – Luis Colorado May 27 '20 at 16:50
  • @LuisColorado yeah... that **is** what I said earlier, that the code **is** outputting correct answer, which **doesn't** help me to solve the problem, so I have edited the above post and put the code for the problem too... so people can get their hands on that. – martin rose Jun 03 '20 at 15:14

2 Answers2

3

Your program produced the correct result.

Take 1e17, i.e. 100,000,000,000,000,000. Integer-divide it by 998,244,353; the quotient is: 100,175,873.

You don't even have to continue the calculation - the divisor and quotient are odd, so their product is odd, so their difference from the even dividend must also be odd. Thus your "correct answer" must be incorrect.

But to continue the calculation - multiply the integer quotient by 998,244,353; you get: 99,999,999,529,095,169.

The difference from 1e17 is indeed 470,904,831.

Now, as @RichardCritten points out, the literal 1e17 is of type double in C++ ... so maybe some floating-point error creeps in somehow in your own computation?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • I am sorry if thats the case... but actually the online modulo calculator gives different answer so I compared it with that... this is the site... https://goodcalculators.com/modulo-calculator/ – martin rose May 26 '20 at 21:04
  • @martinrose: Maybe they should change that site's name to "good +/- 1 calculators dot com" :-) – einpoklum May 26 '20 at 21:42
  • you into competitive coding? I updated my post and now it has code for the problem, can you find the bug? – martin rose May 26 '20 at 22:00
  • @martinrose: That's a different question. Please don't ask a second question "on top of" the first one. – einpoklum May 26 '20 at 22:49
  • yeah... as I read it, It sounds annoying... but please find the bug if you can... – martin rose May 26 '20 at 23:08
2

You are mistaken. The correct answer actually is 470904831.

100'000'000'000'000'000 / 998'244'353 == 100'175'873 + 470'904'831/998'244'353

eerorika
  • 232,697
  • 12
  • 197
  • 326