Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Excellent solution OleGG, But your code is not optimized. I have made following changes to your code,</p> <ol> <li><p>It does not require to go through 9*9*i for k in count_lucky function, because for 10000 cases it would run that many times, instead i have reduced this value through start and end.</p></li> <li><p>i have used ans array to store intermediate results. It might not look like much but over 10000 cases this is the major factor that reduces the time.</p></li> </ol> <p>I have tested this code and it passed all the test cases. Here is the modified code:</p> <pre><code> #include &lt;stdio.h&gt; const int MAX_LENGTH = 18; const int MAX_SUM = 162; const int MAX_SQUARE_SUM = 1458; int primes[1460]; unsigned long long dyn_table[20][164][1460]; //changed here.......1 unsigned long long ans[19][10][164][1460]; //about 45 MB int start[19][163]; int end[19][163]; //upto here.........1 void gen_primes() { for (int i = 0; i &lt;= MAX_SQUARE_SUM; ++i) { primes[i] = 1; } primes[0] = primes[1] = 0; for (int i = 2; i * i &lt;= MAX_SQUARE_SUM; ++i) { if (!primes[i]) { continue; } for (int j = 2; i * j &lt;= MAX_SQUARE_SUM; ++j) { primes[i*j] = 0; } } } void gen_table() { for (int i = 0; i &lt;= MAX_LENGTH; ++i) { for (int j = 0; j &lt;= MAX_SUM; ++j) { for (int k = 0; k &lt;= MAX_SQUARE_SUM; ++k) { dyn_table[i][j][k] = 0; } } } dyn_table[0][0][0] = 1; for (int i = 0; i &lt; MAX_LENGTH; ++i) { for (int j = 0; j &lt;= 9 * i; ++j) { for (int k = 0; k &lt;= 9 * 9 * i; ++k) { for (int l = 0; l &lt; 10; ++l) { dyn_table[i + 1][j + l][k + l*l] += dyn_table[i][j][k]; } } } } } unsigned long long count_lucky (unsigned long long maxp) { unsigned long long result = 0; int len = 0; int split_max[MAX_LENGTH]; while (maxp) { split_max[len] = maxp % 10; maxp /= 10; ++len; } int sum = 0; int sq_sum = 0; unsigned long long step_result; unsigned long long step_; for (int i = len-1; i &gt;= 0; --i) { step_result = 0; int x1 = 9*i; for (int l = 0; l &lt; split_max[i]; ++l) { //changed here........2 step_ = 0; if(ans[i][l][sum][sq_sum]!=0) { step_result +=ans[i][l][sum][sq_sum]; continue; } int y = l + sum; int x = l*l + sq_sum; for (int j = 0; j &lt;= x1; ++j) { if(primes[j + y]) for (int k=start[i][j]; k&lt;=end[i][j]; ++k) { if (primes[k + x]) { step_result += dyn_table[i][j][k]; step_+=dyn_table[i][j][k]; } } } ans[i][l][sum][sq_sum] = step_; //upto here...............2 } result += step_result; sum += split_max[i]; sq_sum += split_max[i] * split_max[i]; } if (primes[sum] &amp;&amp; primes[sq_sum]) { ++result; } return result; } int main(int argc, char** argv) { gen_primes(); gen_table(); //changed here..........3 for(int i=0;i&lt;=18;i++) for(int j=0;j&lt;=163;j++) { for(int k=0;k&lt;=1458;k++) if(dyn_table[i][j][k]!=0ll) { start[i][j] = k; break; } for(int k=1460;k&gt;=0;k--) if(dyn_table[i][j][k]!=0ll) { end[i][j]=k; break; } } //upto here..........3 int cases = 0; scanf("%d",&amp;cases); for (int i = 0; i &lt; cases; ++i) { unsigned long long a, b; scanf("%lld %lld", &amp;a, &amp;b); //changed here......4 if(b == 1000000000000000000ll) b--; //upto here.........4 printf("%lld\n", count_lucky(b) - count_lucky(a-1)); } return 0; } </code></pre> <p>Explanation:</p> <p>gen_primes() and gen_table() are pretty much self explanatory.</p> <p>count_lucky() works as follows:</p> <p>split the number in split_max[], just storing single digit number for ones, tens, hundreds etc. positions. The idea is: suppose split_map[2] = 7, so we need to calculate result for </p> <p>1 in hundreds position and all 00 to 99.</p> <p>2 in hundreds position and all 00 to 99.</p> <p>. .</p> <p>7 in hundreds position and all 00 to 99.</p> <p>this is actually done(in l loop) in terms of sum of digits and sum of square of digits which has been precalcutaled. for this example: sum will vary from 0 to 9*i &amp; sum of square will vary from 0 to 9*9*i...this is done in j and k loops. This is repeated for all lengths in i loop</p> <p>This was the idea of OleGG.</p> <p>For optimization following is considered:</p> <ol> <li><p>its useless to run sum of squares from 0 to 9*9*i as for particular sums of digits it would not go upto the full range. Like if i = 3 and sum equals 5 then sum of square would not vary from 0 to 9*9*3.This part is stored in start[] and end[] arrays using precomputed values.</p></li> <li><p>value for particular number of digits and particular digit at most significant position of number and upto particular sum and upto particular sum of square isstored for memorization. Its too long but still its about 45 MB. I believe this could be further optimized.</p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload