Loading

【题解】The 2022 ICPC Asia Hangzhou Regional Programming Contest (第 47 届 ICPC 国际大学生程序设计竞赛亚洲区域赛(杭州))

D. Money Game

一开始有 \(n\) 个人围成一圈,第 \(i\) 个人手上有 \(a_i\) 的存款(实数),每一轮从第一个人开始,每个人把自己手上的一半存款给下一个人,问稳定时每个人手上存款有多少。

考虑两个人的情况:

\[(x,1) \to (x/2,1+x/2) \to (3/4x+1/2,1/2+x/4) \]

所以:

\[x=2 \]

类似的,三个人的情况可以知道稳态解为:

\[(2,1,1) \]

不难发现,\(n\) 个人的稳态解一定是:

\[(2,1,1,1,1,\cdots,1) \]

相当于每个人给下一个人传了一单位。

\(w=\frac{1}{n+1}\sum_{i=1}^{n} a_i\),则答案为:

\[(2w,w,w,\cdots,w) \]

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

const int N = 1e5 + 10;
typedef long long ll;
int n;
ll a[N];
int main() {
  scanf("%d", &n);
  ll sum = 0;
  for(int i = 1 ; i <= n ; ++ i) {
    scanf("%lld", &a[i]);
    sum += a[i];
  }
  ll prod = n + 1;
  printf("%.6lf ", (double) sum * 2 / prod);
  double tmp = (double) sum / prod;
  for(int i = 2 ; i <= n ; ++ i) {
    printf("%.6lf ", tmp);
  } 
}

F. Da Mi Lao Shi Ai Kan De

签到题,为了防止被卡hash还写了个双hash。

#include <bits/stdc++.h>
using namespace std;
int n;
int len;
set<pair<int, int> > vis;
const int b1 = 149, b2 = 137;
const int m1 = 998244353, m2 = 1e9 + 7;
typedef long long ll;
char str[int(1e5) + 10];
int geths(int b, int m) {
  int res = 0;
  for(int i = 1 ; i <= len ; ++ i) {
    res = ((ll) res * b + str[i]) % m;
  } 
  return res;
}
int hasstr() {
  int h1 = geths(b1, m1);
  int h2 = geths(b2, m2);
  if(vis.find(make_pair(h1, h2)) == vis.end()) {
    vis.insert(make_pair(h1, h2));
    return 0;
  } else {
    return 1;
  }
}
int bie() {
  for(int i = 1 ; i + 2 <= len ; ++ i) {
    if(str[i] == 'b') {
      if(str[i + 1] == 'i' && str[i + 2] == 'e') {
        return 1;
      }
    }
  }
  return 0;
}
int main() {
  scanf("%d", &n);
  for(int i = 1 ; i <= n ; ++ i) {
    int m; scanf("%d", &m);
    int flag = 0;
    while(m --) {
      scanf("%s", str + 1);
      len = strlen(str + 1);
      if(bie()) {
        if(!hasstr()) {
          puts(str + 1);
          flag = 1;
        }
      }
    }
    if(!flag) {
      puts("Time to play Genshin Impact, Teacher Rice!");
    }
  }
}

G. Subgraph Isomorphism

给定一张无向连通图,问它的所有生成树是否同构。

只有当 \(G\) 退化为树或者基环树的时候才可能满足题意。
对于基环树的情况,合法的子树类型只有 (ab)(ab)(ab)(ab) 或者 (a)(a)(a)(a)
树Hash是个玄学东西,可以参考:https://peehs-moorhsum.blog.uoj.ac/blog/7891
看起来只要 \(f\) 足够随机就行,把 \(h\) 数组后面随机加一些 Salt 也能过:

sort(h.begin(), h.end());
ull ret=sz[u]*magic2+dep[u]*magic3;
// 随机撒盐 
srand(sz[u]);
random_shuffle(h.begin(), h.end());
int x = rand() % 10;
for(int i = 0 ; i <= x ; ++ i)
  h.push_back(rand());
for(int i=0;i<(int)h.size();++i)
  ret=ret*magic1+h[i];

J. Painting

\(n\) 条射线,第 \(i\) 条射线从 \((0,a_i)\)\((W,b_i)\) 发射,当碰撞到已经有的射线时会停止。
依次绘制这 \(n\) 条射线,求每条射线停止的位置(用分数表示)。

若某条射线 \(a\) 停止在射线 \(b\) 的某一段,我们考虑将 \(b\) 看作 \(a\) 的父节点,这样所有节点就可以构成一棵树。
对于 \(x=0\) 上任意两个出射点 \(u,v\),路径 \(u \to \text{lca}(u,v) \to v\) 构成一个凸包。
不妨假设 \(y_u>y_v\),则 \(u \to \text{lca}\) 构成上凸壳,\(\text{lca} \to v\) 构成下凸壳。
\(d=\text{lca}(u,v)\),我们考虑在 \([u,d),[v,d)\) 这两条链上分别尝试求出来交点,若都没有交点,则交点在 \(d\) 所在直线上。

不要忘记考虑交点在之前的交点上的情况,比如说 getslope(u,a)==slp,此时 idx 的父节点应该是 u 的父节点。

关于精度问题,求交点时,应该用凸包上的线段所在的原始射线来求交点,而不应该用凸包上的两个交点求交点。
这很好理解,因为求交点会让位数翻倍,凸包上的点全都是 long long 范围,而原始射线端点是 int 范围。
也就是说注释的部分精度问题很大:

// nd[idx] = inj(nd[v], nd[fa[v][0]], Node(0, a), Node(W, b));
nd[idx] = inj(Node(0, :: a[fa[v][0]]), Node(W, :: b[fa[v][0]]), Node(0, a), Node(W, b));
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

struct FastIO {
    static const int S = 2e7;
    int wpos;
    char wbuf[S];
    FastIO() : wpos(0) {}
    inline int xchar() {
      static char buf[S];
      static int len = 0, pos = 0;
      if (pos == len)
        pos = 0, len = fread(buf, 1, S, stdin);
      if (pos == len) exit(0);
      return buf[pos++];
    }
    inline int operator () () {
      int c = xchar(), x = 0, flag = 0;
      while (c <= 32) flag |= c == '-', c = xchar();
      for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
      return flag ? -x : x;
    }
    inline ll operator ! () {
      int c = xchar(); ll x = 0;
      while (c <= 32) c = xchar();
      for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
      return x;
    }
    inline void wchar(int x) {
      if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
      wbuf[wpos++] = x;
    }
    inline void operator () (ll x) {
      if (x < 0) wchar('-'), x = -x;
      char s[24];
      int n = 0;
      while (x || !n) s[n++] = '0' + x % 10, x /= 10;
      while (n--) wchar(s[n]);
//      wchar('\n');
    }
    inline void space(ll x) {
      if (x < 0) wchar('-'), x = -x;
      char s[24];
      int n = 0;
      while (x || !n) s[n++] = '0' + x % 10, x /= 10;
      while (n--) wchar(s[n]);
      wchar(' ');
    }
    inline void nextline() {
      wchar('\n');
    }
    ~FastIO() {
      if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
    }
  } io;
 

const int N = 5e5 + 10;

set<pair<int, int> > segs;
int fa[N][25];
int n, W, cnt, dep[N];

ll gcd(ll a, ll b) {
    if(!a && !b) return 1;
    a = abs(a); b = abs(b);
    return b ? gcd(b, a % b) : a;
}
#define __int128 ll

int getlca(int u, int v) {
    if(dep[u] < dep[v]) swap(u, v);
    for(int i = 20 ; i >= 0 ; -- i) {
        if(dep[fa[u][i]] >= dep[v]) {
            u = fa[u][i];
        }
    }
    if(u == v) return u;
    for(int i = 20 ; i >= 0 ; -- i) {
        if(fa[u][i] != fa[v][i]) {
            u = fa[u][i];
            v = fa[v][i];
        }
    }
    return fa[u][0];
}

int a[N], b[N];
struct Frac {
    ll up, dn;
    Frac(int x = 0) {
        up = x;
        dn = 1;
    }
    void abs() {
        up = :: abs(up);
        dn = :: abs(dn);
        ll g = gcd(up, dn);
        up /= g;
        dn /= g;
    }
};
Frac operator + (Frac a, Frac b) {
    Frac res;
//    ll g;
    __int128 g;
    res.up = (__int128) a.up * b.dn + (__int128) b.up * a.dn;
    res.dn = (__int128) a.dn * b.dn;
    g = gcd(res.up, res.dn);
    res.up /= g;
    res.dn /= g;
    return res;
}
Frac operator - (Frac a, Frac b) {
    b.up *= -1;
    return a + b;
}
Frac operator * (Frac a, Frac b) {
    Frac res;
//    ll g;
    __int128 g;
    res.up = (__int128) a.up * b.up;
    res.dn = (__int128) a.dn * b.dn;
    g = gcd(res.up, res.dn);
    res.up /= g;
    res.dn /= g;
    return res;
}
Frac operator / (Frac a, Frac b) {
    Frac res;
//    ll g;
    __int128 g;
    res.up = (__int128) a.up * b.dn;
    res.dn = (__int128) a.dn * b.up;
    g = gcd(res.up, res.dn);
    res.up /= g;
    res.dn /= g;
    return res;
}
Frac operator - (Frac a) {
    a.up *= -1;
    return a;
}
bool operator <= (Frac a, Frac b) {
    if(a.dn < 0) a.up *= -1, a.dn *= -1;
    if(b.dn < 0) b.up *= -1, b.dn *= -1;
    return (__int128) a.up * b.dn <= (__int128) b.up * a.dn;
}
bool operator >= (Frac a, Frac b) {
    if(a.dn < 0) a.up *= -1, a.dn *= -1;
    if(b.dn < 0) b.up *= -1, b.dn *= -1;
    return (__int128) a.up * b.dn >= (__int128) b.up * a.dn;
}
bool operator == (Frac a, Frac b) {
    return (__int128) a.up * b.dn == (__int128) b.up * a.dn;
}

struct Node {
    Frac x, y;
    Node(int ix = 0, int iy = 0) {
        x = Frac(ix);
        y = Frac(iy);
    }
    void abs() {
        x.abs();
        y.abs();
    }
} nd[N];
Node operator * (Node a, Frac b) {
    a.x = a.x * b;
    a.y = a.y * b;
    return a;
}
Node operator / (Node a, Frac b) {
    a.x = a.x / b;
    a.y = a.y / b;
    return a;
}
Node operator + (Node a, Node b) {
    a.x = a.x + b.x;
    a.y = a.y + b.y;
    return a;
}

#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
Node inj(Node p1, Node p2, Node q1, Node q2) {
    Frac a1 = cross(q1,q2,p1);
    Frac a2 = -cross(q1,q2,p2);
    return (p1 * a2 + p2 * a1) / (a1 + a2);
}

Frac getslope(int idx, int a) {
    Node p = nd[idx];
    Node q = Node(0, a);
    Frac res = (p.y - q.y) / (p.x - q.x);
    return res;
}

int getfa(int idx, int a, int b) {
    if(segs.empty()) {
        nd[idx] = Node(W, b);
        return n + 1;
    }
    int u, v;
    if(segs.begin() -> first > a) {
        u = segs.begin() -> second;
        v = n + 1;
    } else if((-- segs.end()) -> first < a) {
        u = n + 1;
        v = (-- segs.end()) -> second;
    } else {
        auto it = segs.lower_bound(make_pair(a, 0));
        u = it -> second;
        v = (-- it) -> second;
    }
    int d = getlca(u, v);
    Frac slp = Frac(b-a) / Frac(W);
    if(u != d) {
        if(getslope(u, a) <= slp) {
            nd[idx] = inj(Node(0, :: a[u]), Node(W, :: b[u]), Node(0, a), Node(W, b));
            return getslope(u, a) == slp ? fa[u][0] : u;
        } else {
            for(int i = 20 ; i >= 0 ; -- i) {
                if(dep[fa[u][i]] <= dep[d]) continue;
                if(getslope(fa[u][i], a) >= slp) {
                    u = fa[u][i];
                }
            }
            if(getslope(u, a) >= slp) {
                if(getslope(u, a) == slp) {
                    nd[idx] = nd[u];
                    return fa[u][0];
                } else if(fa[u][0] != d && getslope(fa[u][0], a) <= slp) {
//                    nd[idx] = inj(nd[u], nd[fa[u][0]], Node(0, a), Node(W, b));
                    nd[idx] = inj(Node(0, :: a[fa[u][0]]), Node(W, :: b[fa[u][0]]), Node(0, a), Node(W, b));
                    return fa[u][0];
                }
            }
        }
    }
    
    if(v != d) {
        if(getslope(v, a) >= slp) {
            nd[idx] = inj(Node(0, :: a[v]), Node(W, :: b[v]), Node(0, a), Node(W, b));
            return getslope(v, a) == slp ? fa[v][0] : v;
        } else {
            for(int i = 20 ; i >= 0 ; -- i) {
                if(dep[fa[v][i]] <= dep[d]) continue;
                if(getslope(fa[v][i], a) <= slp) {
                    v = fa[v][i];
                }
            }
            if(getslope(v, a) <= slp) {
                if(getslope(v, a) == slp) {
                    nd[idx] = nd[v];
                    return fa[v][0];
                } else if(fa[v][0] != d && getslope(fa[v][0], a) >= slp) {
//                    nd[idx] = inj(nd[v], nd[fa[v][0]], Node(0, a), Node(W, b));
                    nd[idx] = inj(Node(0, :: a[fa[v][0]]), Node(W, :: b[fa[v][0]]), Node(0, a), Node(W, b));
                    return fa[v][0];
                }
            }
        }
    }
    if(d == n + 1) {
        nd[idx] = Node(W, b);
        return n + 1;
    } else {
        nd[idx] = inj(Node(0, :: a[d]), Node(W, :: b[d]), Node(0, a), Node(W, b));
        return d;
    }
}

int main() {
    n = io(), W = io();
    dep[n + 1] = 1;
    for(int i = 0 ; i <= 20 ; ++ i) {
        fa[n + 1][i] = n + 1;
    }
    for(int i = 1 ; i <= n ; ++ i) {
        int a, b, c;
        a = io(), b = io(), c = io();
        :: a[i] = a, :: b[i] = b;
        int f = getfa(i, a, b);
        if(c) {
            segs.insert(make_pair(a, i));
            fa[i][0] = f;
            dep[i] = dep[f] + 1;
            for(int j = 1 ; j <= 20 ; ++ j) {
                fa[i][j] = fa[fa[i][j - 1]][j - 1];
            }
        }
        nd[i].abs();
        io.wchar('(');
        io(nd[i].x.up);
        io.wchar('/');
        io(nd[i].x.dn);
        io.wchar(',');
        io(nd[i].y.up);
        io.wchar('/');
        io(nd[i].y.dn);
        io.wchar(')');
        io.wchar('\n');
    }
}

M. Please Save Pigeland

给定一棵 \(n\) 个点的树,上面有 \(k\) 个关键点,对于每一个点 \(u\),求:

  1. \(u\) 到所有关键点的距离之和;
  2. \(u\) 到所有关键点的距离的 \(\gcd\)

首先 \(u=1\) 时,这两个信息都很容易求到,考虑换根的同时维护这两个信息。

将关键点的 dfs 序离散化,当转移 \(u \to v\) 时(边权为 \(w\)),相当于把在 \(v\) 子树内的关键点距离都减去 \(w\),然后把在 \(V\) 子树外的关键点距离都加上 \(w\),即在 dfs 序上是维护区间加,然后查询全区间的和。

对于 \(\gcd\) 信息,由更相减损术可知:

\[\boxed{ \gcd(a_1,a_2,\cdots,a_n)=\gcd(a_1,a_2-a_1,a_3-a_2,\cdots,a_n-a_{n-1}) } \]

因此只需要维护差分数组的 \(\gcd\),然后求 \([2,n]\)\(\gcd\) 与原数组 \([1,1]\)\(\gcd\) 即可。

需要注意一些边界情况:

  1. \(k=1\),则答案为 \(0\)
  2. 若某一个点的子树中无关键点,则转移到这个点时应该将全区间的距离都加上 \(w\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct FastIO {
  static const int S = 2e7;
  int wpos;
  char wbuf[S];
  FastIO() : wpos(0) {}
  inline int xchar() {
    static char buf[S];
    static int len = 0, pos = 0;
    if (pos == len)
    pos = 0, len = fread(buf, 1, S, stdin);
    if (pos == len) exit(0);
    return buf[pos++];
  }
  inline int operator () () {
    int c = xchar(), x = 0, flag = 0;
    while (c <= 32) flag |= c == '-', c = xchar();
    for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
    return flag ? -x : x;
  }
  inline ll operator ! () {
    int c = xchar(); ll x = 0;
    while (c <= 32) c = xchar();
    for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
    return x;
  }
  inline void wchar(int x) {
    if (wpos == S) fwrite(wbuf, 1, S, stdout), wpos = 0;
    wbuf[wpos++] = x;
  }
  inline void operator () (ll x) {
    if (x < 0) wchar('-'), x = -x;
    char s[24];
    int n = 0;
    while (x || !n) s[n++] = '0' + x % 10, x /= 10;
    while (n--) wchar(s[n]);
    wchar('\n');
  }
  inline void space(ll x) {
    if (x < 0) wchar('-'), x = -x;
    char s[24];
    int n = 0;
    while (x || !n) s[n++] = '0' + x % 10, x /= 10;
    while (n--) wchar(s[n]);
    wchar(' ');
  }
  inline void nextline() {
    wchar('\n');
  }
  ~FastIO() {
    if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
  }
} io;

const int N = 1e6 + 10;
int n, k;
int head[N], rest[N * 2], to[N * 2], w[N * 2], tot;
void add(int u, int v, int w) {
  to[++ tot] = v;
  :: w[tot] = w;
  rest[tot] = head[u];
  head[u] = tot;
}
int imp[N];
int clk, dfnl[N], dfnr[N], rev[N], tid[N];
ll dep[N];
int sz[N];
ll bgcd(ll a, ll b) {
  return b ? bgcd(b, a % b) : a;
}
#define lc (id << 1)
#define rc (id << 1 | 1)
namespace seg_diff {	
  ll gcd[N * 8];
  void modify(int id, int l, int r, int pos, ll val) {
    if(pos < l || pos > r) return ;
    int mid = (l + r) >> 1;
    if(l == r) {
      gcd[id] += val;
      return ;
    } else if(pos <= mid) {
      modify(lc, l, mid, pos, val);
    } else {
      modify(rc, mid + 1, r, pos, val);
    }
    gcd[id] = bgcd(gcd[lc], gcd[rc]);
  }
  ll query(int id, int l, int r, int ql, int qr) {
    int mid = (l + r) >> 1;
    if(ql <= l && r <= qr) {
      return gcd[id];
    } else if(qr < l || ql > r) {
      return 0;
    } else {
      return bgcd(query(lc, l, mid, ql, qr), query(rc, mid + 1, r, ql, qr));
    }
  }
};

namespace seg_norm {
  ll tag[N * 8], sum[N * 8];
  void modify(int id, int l, int r, int ql, int qr, ll val) {
    if(ql <= l && r <= qr) {
      tag[id] += val; 
    } else if(qr < l || ql > r) {
      return ;
    } else {
      int mid = (l + r) >> 1;
      sum[id] += val * (min(r, qr) - max(l, ql) + 1);
      modify(lc, l, mid, ql, qr, val);
      modify(rc, mid + 1, r, ql, qr, val);
    }
  }
  ll query(int id, int l, int r, int ql, int qr) {
    if(ql <= l && r <= qr) {
      return sum[id] + tag[id] * (r - l + 1);
    } else if(qr < l || ql > r) {
      return 0;
    } else {
      int mid = (l + r) >> 1;
      ll t = tag[id] * (min(r, qr) - max(l, ql) + 1);
      return t + query(lc, l, mid, ql, qr) + query(rc, mid + 1, r, ql, qr);
    }
  }
};

ll ans_dis[N], ans_gcd[N];
int rev_l[N], rev_r[N];

signed main() {
  n = io(), k = io();
  for(int i = 1, x ; i <= k ; ++ i) {
    imp[io()] = 1;
  }
  for(int i = 1 ; i < n ; ++ i) {
    int u = io(), v = io(), w = io();
    add(u, v, w);
    add(v, u, w);
  }
  
  if(k == 1) {
    puts("0");
    return 0;
  }
  
  if(1) {
    function<void(int, int)> dfs = [&] (int u, int fa) {
      ++ clk;
      dfnl[u] = clk;
      tid[clk] = u;
      sz[u] = imp[u];
      for(int i = head[u] ; i ; i = rest[i]) {
        int v = to[i];
        if(v == fa) continue;
        dep[v] = dep[u] + w[i];
        dfs(v, u);
        sz[u] += sz[v];
      }
      dfnr[u] = clk;
    };
    dfs(1, 0);
  }

  vector<int> lsh;
  for(int i = 1 ; i <= n ; ++ i) {
    if(imp[i]) {
      lsh.push_back(dfnl[i]);
    }
  }
  sort(lsh.begin(), lsh.end());
  lsh.erase(unique(lsh.begin(), lsh.end()), lsh.end());
  for(int i = 1 ; i <= n ; ++ i) {
    rev[i] = lower_bound(lsh.begin(), lsh.end(), dfnl[i]) - lsh.begin() + 1;
    rev_l[i] = rev[i];
    rev_r[i] = upper_bound(lsh.begin(), lsh.end(), dfnr[i]) - lsh.begin();	
    rev_r[i] = max(rev_r[i], rev_l[i]);
  }
  int len = lsh.size();
  vector<int> arr;
  for(int i = 0 ; i < len ; ++ i) {
    arr.push_back(tid[lsh[i]]);
  }
  for(int i = 0 ; i < len ; ++ i) {
    seg_norm :: modify(1, 1, len, i + 1, i + 1, dep[arr[i]]);
    seg_diff :: modify(1, 1, len, i + 1, dep[arr[i]] - (i==0?0:dep[arr[i-1]]));
  }
  if(1) {
    function<void(int, int)> dfs = [&] (int u, int fa) {
      ans_dis[u] = seg_norm :: query(1, 1, len, 1, len);
      ans_gcd[u] = bgcd(seg_norm :: query(1, 1, len, 1, 1),
             seg_diff :: query(1, 1, len, 2, len));
      for(int i = head[u] ; i ; i = rest[i]) {
        int v = to[i];
        if(v == fa) continue;
        if(sz[v] == 0) {
          seg_norm :: modify(1, 1, len, 1, len, w[i]);
          seg_diff :: modify(1, 1, len, 1, w[i]);
          dfs(v, u);
          seg_norm :: modify(1, 1, len, 1, len, -w[i]);
          seg_diff :: modify(1, 1, len, 1, -w[i]);
        } else {
          seg_norm :: modify(1, 1, len, rev_l[v], rev_r[v], -w[i]);
          seg_norm :: modify(1, 1, len, 1, rev_l[v]-1, w[i]);
          seg_norm :: modify(1, 1, len, rev_r[v]+1, len, w[i]);
          seg_diff :: modify(1, 1, len, 1, w[i]);
          seg_diff :: modify(1, 1, len, rev_l[v], -2*w[i]);
          seg_diff :: modify(1, 1, len, rev_r[v]+1, 2*w[i]);
          dfs(v, u);
          seg_norm :: modify(1, 1, len, rev_l[v], rev_r[v], w[i]);
          seg_norm :: modify(1, 1, len, 1, rev_l[v]-1, -w[i]);
          seg_norm :: modify(1, 1, len, rev_r[v]+1, len, -w[i]);
          seg_diff :: modify(1, 1, len, 1, -w[i]);
          seg_diff :: modify(1, 1, len, rev_l[v], 2*w[i]);
          seg_diff :: modify(1, 1, len, rev_r[v]+1, -2*w[i]);
        }
      }
    };
    dfs(1, 0);
  }
  ll ans = ans_dis[1] / abs(ans_gcd[1]);
  for(int i = 1 ; i <= n ; ++ i) {
    ans = min(ans, ans_dis[i] / abs(ans_gcd[i]));
  }
  printf("%lld\n", ans * 2);
}
posted @ 2022-12-05 16:20  nekko  阅读(3203)  评论(0)    收藏  举报