2024.7.5

Orz AKer / 2024-07-08 / 原文

数字涡旋

可以发现, 可以差成一个__| 形状的东西, 而且是有顺序的, 找到那一行后输出坐标

#include<bits/stdc++.h>

using namespace std;

int op, n, T;

void S(){
  cin >> n;
  op = sqrt(n);
  op += (op * op != n);
  n = op * op - n + 1;
  if(op & 1){
    if(n <= op){
      cout << n << ' ' << op << '\n';
    }
    else{
      cout << op << ' ' << op - (n - op) << '\n';
    }
  }
  else{
    if(n <= op){
      cout << op << ' ' << n << '\n';
    }
    else{
      cout << op - (n - op) << ' ' << op << '\n';
    }
  }
}

int main(){
  ios::sync_with_stdio(0), cin.tie(0);
  freopen("spiral.in", "r", stdin);
  freopen("spiral.out", "w", stdout);
  for(cin >> T; T--; S()){
  }
  return 0;
}

时间复杂度 \(O(T)\)

空间复杂度 \(O(1)\)

潦草急就

如果对于 k 进制下每一位考虑, 可以发现构成了一个循环然后推式子就可以了

从右往左第 \(i\) 位每 \(k^{i - 1}\) 次方一个循环

#include<bits/stdc++.h>

using namespace std;

const int N = 100, mod = 2027;

long long n, oo, y, ok;
long long k, ans[N], bpow[N], cnt, T, s;

void S(){
  cin >> n >> k;
  for(int i = 0; i < k; ++i){
    ans[i] = 0;
  }
  ok = n + 1;
  for(long long i = 1; i <= n; i *= k){
    oo = ok / (i * k) * i, y = (ok % (i * k)) / i;
    ans[0] = (ans[0] + oo), ans[k] = ((ans[k] - oo));
    if(ok % (i * k)){
      if((ok % (i * k)) % i){
        ans[0] = (ans[0] + i), ans[y] = ((ans[y] - i));
        ans[y] = (ans[y] + (ok % (i * k)) % i);
        ans[y + 1] = ((ans[y + 1] - (ok % (i * k)) % i));
      }
      else{
        ans[0] = (ans[0] + i), ans[y] = ((ans[y] - i));
      }
    }
  }
  for(ok = n, n = 0; ok; ok /= k, n++){
  }
  bpow[0] = 1;
  for(int i = 1; i <= n; ++i){
    bpow[i] = 1ll * bpow[i - 1] * k;
  }
  cnt = 0;
  for(int i = 2; i <= n; ++i){
    cnt = (cnt + 1ll * (i - 1) * (1ll * (k - 1) * bpow[n - i]));
  }
  cnt += (n - 1);
  cnt %= mod;
  cout << ((ans[0] - cnt) % mod + mod) % mod << ' ';
  for(int i = 1; i < k; ++i){
    ans[i] = ((ans[i] + ans[i - 1]) % mod + mod) % mod;
    cout << ans[i] << ' ';
  }
  cout << '\n';
}

int main(){
  ios::sync_with_stdio(0), cin.tie(0);
  freopen("write.in", "r", stdin);
  freopen("write.out", "w", stdout);
  for(cin >> T; T--; S()){
  }
  return 0;
}

时间复杂度 \(O(T \cdot (k + log_k n))\)

空间复杂度 \(O(k)\)

取模常数过大, 答案不会爆 long long 所以可以最后再取模

柳暗花明

先把详细取整差掉, 答案肯定小于差后

ans = \(x / 2^{r - l + 1} + a_l / 2^{r - l + 1} + a_{l - 1} / 2^{r - l} + \dots a_r / 2\)

对于答案 \(/ 2^100\) 的答案, 贡献很小, 又有向下取整, 所以不用考虑

#include<bits/stdc++.h>

using namespace std;

const int N = 2e5 + 5;

int n, q, a[N], x, l, r;

int main(){
  ios::sync_with_stdio(0), cin.tie(0);
  freopen("curve.in", "r", stdin);
  freopen("curve.out", "w", stdout);
  cin >> n;
  for(int i = 1; i <= n; ++i){
    cin >> a[i];
  }
  cin >> q;
  while(q--){
    cin >> x >> l >> r;
    for(int i = max(l, r - 100); i <= r; ++i){
      x = (x + a[i]) / 2;
    }
    cout << x << '\n';
  }
  return 0;
}

时间复杂度 \(O(n + 100q)\)

空间复杂度 \(O(n)\)

移动硬币

\(w_i \le 1000000\)

考虑取模状态设计的 dij

状态 \((i, sum)\) 表示构成 \(\bmod a_1\) 后为 \(i\) 的最小 \(sum\), 这样, \(sum + k \cdot a_1\) 都可以被构造出来

转移 \((i, sum) \to ((i + a_j) \bmod a_1, sum + a_j)\)

#include<bits/stdc++.h>

using namespace std;

const int N = 1e6 + 5;

struct Node{
  int u;
  long long d;
};

struct Edge{
  int u, w;
};

struct cmp{
  bool operator()(const Node &i, const Node &j){
    return i.d > j.d;
  }
};

priority_queue<Node, vector<Node>, cmp>pq;
int a[100], n;
bool vis[N];
long long dist[N], l, ans;

void dij(){
  for(int i = 1; i < a[1]; ++i){
    dist[i] = l + 1;
  }
  pq.push({0, 0});
  while(pq.size()){
    auto [u, d] = pq.top();
    pq.pop();
    if(vis[u]){
      continue;
    }
    vis[u] = 1;
    for(int i = 1; i <= n; ++i){
      auto v = (u + a[i]) % a[1], w = a[i];
      if(dist[v] > dist[u] + w){
        dist[v] = dist[u] + w;
        pq.push({v, dist[v]});
      }
    }
  }
}

int main(){
  freopen("coin.in", "r", stdin);
  freopen("coin.out", "w", stdout);
  cin >> n >> l;
  for(int i = 1; i <= n; ++i){
    cin >> a[i];
  }
  sort(a + 1, a + n + 1, [](const int &i, const int &j){  return i > j;});
  dij();
  for(int i = 0; i < a[1]; ++i){
    if(dist[i] <= l){
      ans += (l - dist[i]) / a[1] + 1;
    }
  }
  cout << ans - 1;
  return 0;
}

时间复杂度 \(O(n \cdot a_1 \log_2 a_1)\)

空间复杂度 \(O(a_1 + n)\)