Problem p02609 (C++) — buggy submission, verdict: Time Limit Exceeded


// Problem : D - Anything Goes to Zero
// Contest : AtCoder - AIsing Programming Contest 2020
// URL : https://atcoder.jp/contests/aising2020/tasks/aising2020_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

using ll = long long;
using ull = unsigned long long;
using db = double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using mapl = map<ll, ll>;
using mapc = map<char, ll>;
using vectorl = vector<ll>;
using vectors = vector<string>;
const int N = 2e5 + 10;
const ll inf = 1e15 + 42;
#define pb push_back
#define endl "\\n"
const ll mod = 1000000007;

ll i = 0, j = 0, k = 0, t = 0, n = 0;

char x = 'a', y = 'a', z = 'a';
string s = "", s1 = "";

vectorl pr;
void seive(int n) {
  bool prime[n + 1];
  memset(prime, true, sizeof(prime));

  for (int p = 2; p * p <= n; p++) {
    if (prime[p] == true) {
      for (int i = p * p; i <= n; i += p)
        prime[i] = false;
    }
  }
  for (int p = 2; p <= n; p++)
    if (prime[p])
      pr.push_back(p);
}

double log_base(ll x, ll base) { return ((log(x) * 1.0) / (log(base) * 1.0)); }

ll calcInverse(ll a, ll n) {
  ll t = 0, newt = 1;
  ll r = n, newr = a;
  while (newr != 0) {
    auto quotient = r / newr;
    tie(t, newt) = make_tuple(newt, t - quotient * newt);
    tie(r, newr) = make_tuple(newr, r - quotient * newr);
  }
  if (r > 1)
    throw runtime_error("a is not invertible");
  if (t < 0)
    t += n;

  t = t % mod;
  return t;
}

ll power_without_mod(ll a, ll b) {
  ll ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans = ans * a;
    }
    a = a * a;
    b >>= 1;
  }
  return ans;
}

ll power(ll a, ll b, ll mod1) {
  a %= mod1;
  ll ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans = ans * a % mod1;
    }
    a = a * a % mod1;
    b >>= 1;
  }
  return ans;
}

// if mod is prime: calculate x^(n mod (m-1))
// if  is string   find number calculating with mod of (m-1)

// for ex:
//  string b = "100000000000000000000000000";

//     ll remainderB = 0;
//     ll MOD = 1000000007;

//     // Reduce the number B to a small number
//     // using Fermat Little
//     for (int i = 0; i < b.length(); i++)
//         remainderB = (remainderB * 10 + b[i] - '0') % (MOD - 1);

//     cout << power(a, remainderB, MOD) << endl;

void multiply(ll a[3][3], ll b[3][3]) {
  // Creating an auxiliary matrix to store elements
  // of the multiplication matrix
  ll mul[3][3];
  for (ll i = 0; i < 3; i++) {
    for (ll j = 0; j < 3; j++) {
      mul[i][j] = 0;
      for (ll k = 0; k < 3; k++)
        mul[i][j] =
            (mul[i][j] + ((a[i][k] % mod) * (b[k][j] % mod)) % mod) % mod;
    }
  }

  // storing the multiplication result in a[][]
  for (ll i = 0; i < 3; i++)
    for (ll j = 0; j < 3; j++)
      a[i][j] = mul[i][j]; // Updating our matrix
}

// Function to compute F raise to power n-2.
ll power_matrix(ll F[3][3], ll n) {
  ll result[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
  while (n > 0) {
    if (n % 2 == 1) {
      multiply(result, F);
    }
    multiply(F, F);
    n /= 2;
  }
  return result[0][0] * 3 + result[0][2];
}

void solve() {
  ll n;
  cin >> n;
  string s;
  cin >> s;
  ll x = 0, x2 = 0;
  ll co = 0;
  for (i = 0; i < s.length(); i++) {
    if (s[i] == '1') {
      co++;
    }
  }
  vector<ll> v1, v2;
  for (i = 0; i < s.length(); i++) {

    v1.pb(power(2, s.length() - i - 1, co + 1));
    if ((co - 1) > 0)
      v2.pb(power(2, s.length() - i - 1, co - 1));
    if (s[i] == '1') {
      x += power(2, s.length() - i - 1, co + 1);
      // cout<<x<<" "<<s.length()-i-1<<endl;
      x %= (co + 1);
      if ((co - 1) > 0) {
        x2 += power(2, s.length() - i - 1, co - 1);
        x2 %= (co - 1);
      }
    }
  }
  // cout<<x<<" "<<x2<<endl;
  for (i = 0; i < n; i++) {
    ll temp, temp2 = co, ans = 0;

    if (s[i] == '0') {
      // ans++;
      temp = x;
      temp2++;
      temp += (v1[i]);
      while (1) {
        ans++;
        temp = temp % temp2;
        bitset<60> b1(temp);
        temp2 = b1.count();
        if (temp == 0)
          break;
      }
      cout << ans << endl;
    } else {
      temp = x2;
      temp2--;
      temp -= v2[i];
      if (co == 1) {
        cout << 0 << endl;
        continue;
      }

      // ans++;
      // cout<<temp<<" ";
      while (temp < 0) {
        temp += (temp2);
      }
      while (1) {
        ans++;
        temp = temp % temp2;
        bitset<60> b1(temp);
        temp2 = b1.count();
        if (temp == 0)
          break;
      }
      cout << ans << endl;
    }

    // cout<<ans<<endl;
  }
}

int main() {
  ios_base ::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  // ll t;
  // cin>>t;
  // while(t--){
  solve();
  // }
  return 0;
}


Error: TLE

Fixed submission:


// Problem : D - Anything Goes to Zero
// Contest : AtCoder - AIsing Programming Contest 2020
// URL : https://atcoder.jp/contests/aising2020/tasks/aising2020_d
// Memory Limit : 1024 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

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

using ll = long long;
using ull = unsigned long long;
using db = double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using mapl = map<ll, ll>;
using mapc = map<char, ll>;
using vectorl = vector<ll>;
using vectors = vector<string>;
const int N = 2e5 + 10;
const ll inf = 1e15 + 42;
#define pb push_back
#define endl "\\n"
const ll mod = 1000000007;

ll i = 0, j = 0, k = 0, t = 0, n = 0;

char x = 'a', y = 'a', z = 'a';
string s = "", s1 = "";

vectorl pr;
void seive(int n) {
  bool prime[n + 1];
  memset(prime, true, sizeof(prime));

  for (int p = 2; p * p <= n; p++) {
    if (prime[p] == true) {
      for (int i = p * p; i <= n; i += p)
        prime[i] = false;
    }
  }
  for (int p = 2; p <= n; p++)
    if (prime[p])
      pr.push_back(p);
}

double log_base(ll x, ll base) { return ((log(x) * 1.0) / (log(base) * 1.0)); }

ll calcInverse(ll a, ll n) {
  ll t = 0, newt = 1;
  ll r = n, newr = a;
  while (newr != 0) {
    auto quotient = r / newr;
    tie(t, newt) = make_tuple(newt, t - quotient * newt);
    tie(r, newr) = make_tuple(newr, r - quotient * newr);
  }
  if (r > 1)
    throw runtime_error("a is not invertible");
  if (t < 0)
    t += n;

  t = t % mod;
  return t;
}

ll power_without_mod(ll a, ll b) {
  ll ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans = ans * a;
    }
    a = a * a;
    b >>= 1;
  }
  return ans;
}

ll power(ll a, ll b) {
  a %= mod;
  ll ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans = ans * a % mod;
    }
    a = a * a % mod;
    b >>= 1;
  }
  return ans;
}

// if mod is prime: calculate x^(n mod (m-1))
// if  is string   find number calculating with mod of (m-1)

// for ex:
//  string b = "100000000000000000000000000";

//     ll remainderB = 0;
//     ll MOD = 1000000007;

//     // Reduce the number B to a small number
//     // using Fermat Little
//     for (int i = 0; i < b.length(); i++)
//         remainderB = (remainderB * 10 + b[i] - '0') % (MOD - 1);

//     cout << power(a, remainderB, MOD) << endl;

void multiply(ll a[3][3], ll b[3][3]) {
  // Creating an auxiliary matrix to store elements
  // of the multiplication matrix
  ll mul[3][3];
  for (ll i = 0; i < 3; i++) {
    for (ll j = 0; j < 3; j++) {
      mul[i][j] = 0;
      for (ll k = 0; k < 3; k++)
        mul[i][j] =
            (mul[i][j] + ((a[i][k] % mod) * (b[k][j] % mod)) % mod) % mod;
    }
  }

  // storing the multiplication result in a[][]
  for (ll i = 0; i < 3; i++)
    for (ll j = 0; j < 3; j++)
      a[i][j] = mul[i][j]; // Updating our matrix
}

// Function to compute F raise to power n-2.
ll power_matrix(ll F[3][3], ll n) {
  ll result[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
  while (n > 0) {
    if (n % 2 == 1) {
      multiply(result, F);
    }
    multiply(F, F);
    n /= 2;
  }
  return result[0][0] * 3 + result[0][2];
}

void solve() {
  ll n;
  cin >> n;
  string s;
  cin >> s;
  ll x = 0;
  ll co = 0;
  for (i = s.length() - 1; i >= 0; i--) {
    if (s[i] == '1') {
      x += power_without_mod(2, s.length() - 1 - i);
      co++;
    }
  }
  // ll temp=x,temp2=co;

  for (i = 1; i <= n; i++) {
    ll temp = x, temp2 = co, ans = 0;

    if (s[i - 1] == '0') {
      temp2++;
      temp += power_without_mod(2, s.length() - i);
    } else {
      temp2--;
      temp -= power_without_mod(2, s.length() - i);
    }
    while (temp != 0) {
      temp = temp % temp2;
      bitset<32> b1(temp);
      temp2 = b1.count();
      ans++;
    }
    cout << ans << endl;
  }
}

int main() {
  ios_base ::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  // ll t;
  // cin>>t;
  // while(t--){
  solve();
  // }
  return 0;
}