首页 > 其他分享 >AT_agc003_e 题解

AT_agc003_e 题解

时间:2023-04-16 19:45:53浏览次数:51  
标签:agc003 cnt 函数 int 题解 len 循环 solve

题目链接

神仙题,我会把我自己思考的过程一步步写出来。

初看这题时感觉没什么思路,所以随便算了点东西。很容易发现如果对于一个 $i$,$q_i\geq q_{i+1}$,那么 $q_i$ 就没有意义,每次把元素放进来时先把头部比它大的都弹走,再把它放进去,设处理完的 size 为 cnt。

然后就是这道题的精髓所在了!很容易就可以发现 $q_i+1$ 的串是 $q_i$ 串的弱循环。所以就可以弄一个 solve 函数,solve (x, y) 意思是处理第 $q$ 个串循环 $y$ 遍的贡献。运行 solve (cnt, 1) 就可以了,但是 solve 函数怎么设计呢?

以下设 $q_i=len_i$

前面的循环节可以用 solve (cnt - 1, len[cnt] / len[cnt - 1]) 处理,但是后面多余的呢?

这时我们发现需要改变 solve 函数了,设 solve (x, y) 为处理前 $x$ 个字符循环 $y$ 次的贡献。

转移首先要找到第一个 $t$,使得 $len[t] < x$,前面的部分仍然是循环,solve (len[t], x / len[t]) 就解决了,后面还有 $x$ $\bmod$ $len[t]$ 个剩余的,这些只循环 1 次,solve (x % len[t], 1) 就可以了。

另外,注意下边界问题,如果 $x\leq n$ 了,那么前 $x$ 个字符就是 $1\cdots x$,这些的出现次数都 $+1$,用差分维护就行。

分析一下时间复杂度,$T(x)= x + T(x - 1) + T (\frac{x}{2})=x^2$,考虑优化。

时间主要用在了 $x$ 和 $T(x-1)$ 上,第一个用二分可以 $\log_n$。关于第二个,solve 函数都是 solve (len[t], x / len[t]) 的形式,第一个参数也就 $n$ 种。因此,我们用一个桶 $f$,$f[t]$ 统计的是 $1$ 到 $len[t]$ 个字符循环的次数(即出现在最终字符串中的次数)。最后再把 $f$ 中的一起统计一下就行。

现在的 solve 函数就成了这样:

void solve (int x, int y) {
    if (x <= n) {
        d[1] += y;
        d[x + 1] -= y;
        return;
   }
   int t = lower_bound (len + 1, len + cnt + 1, x) - len - 1;
   f[t] += x / a[t] * y;
   solve (x % a[t], y);
}

 

结束后,我们倒序循环一下。$f[i]$ 拆成 $f[i - 1] * \lfloor\frac{len[i]}{len[i - 1]}\rfloor + len[i] $ $\bmod$ $len[i - 1]$,前面的加到 $f[i-1]$ 上,后面的继续用 solve 函数。(即 solve (len[i] % len[i - 1], f[i]) )。

此题的 $q_i$ 也可能小于 $n$,所以遇到这种情况,我们把 $n$ 设为最小的 $q_i$,输出时 $>n$ 的输出 $0$ 即可。

这样,时间复杂度降到了 $n\log^2 n$,另外注意开长整型和特判 $q=0$ 的情况。

少量注释的代码:

#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
int n, q, cnt;
int a[100005], d[100005], f[100005];
void solve (int x, int y) {//求解前 x 个字符的贡献乘上 y 
    if (x <= n) {
        d[1] += y;
        d[x + 1] -= y;
        return;
    }
    int t = lower_bound (a + 1, a + cnt + 1, x) - a - 1;
    f[t] += x / a[t] * y;//其实是前 a[t] 个字符乘上 x / a[t] 加上剩余的。 
    solve (x % a[t], y);
}
signed main () {
    int x, z;
    cin >> n >> q;
    if (q == 0) {
        for (int i = 1; i <= n; i ++) cout << 1 << "\n";
        return 0;
    }
    z = n;
    a[++ cnt] = n;
    for (int i = 1; i <= q; i ++) {
        cin >> x;
        n = min (n, x);
        while (cnt != 0 && a[cnt] >= x) -- cnt;
        a[++ cnt] = x;
    }
    solve (x, 1);
    for (int i = cnt; i >= 2; i --) {
        f[i - 1] += a[i] / a[i - 1] * f[i];
        solve (a[i] % a[i - 1], f[i]);
    }
    d[1] += f[1];
    d[n + 1] -= f[1];
    for (int i = 1; i <= n; i ++) {
        d[i] += d[i - 1];
        cout << d[i] << "\n";
    }
    for (int i = n + 1; i <= z; i ++) cout << 0 << "\n";
    return 0;
}

 

标签:agc003,cnt,函数,int,题解,len,循环,solve
From: https://www.cnblogs.com/Xy-top/p/17323879.html

相关文章

  • Atcoder题解:Agc002_f
    我们可以把这个理解成一种类似卡塔兰数的形式,我们发现,被安排的\(0\)球总数\(i\)和已经出现的颜色种数\(j\)在任意时刻都必须满足\(i\gej\)。然后就可以\(dp\)了,我们每次钦定下一个转移的球是某种颜色。如果下一个转移的球不是\(0\),那么我们就一次性把后面所有这种颜色......
  • Atcoder题解:Agc004_e
    \[吓死我了,还以为写了半天的被自己删掉了\]\[但是\text{Ctrl+S}会保存草稿啊\]\[以后一定要保留这个好习惯\]第一步转化题意,我们把“所有机器人移动”转化成“出口带着边框移动”,而在出口运动过程中超出边框的机器人,就“死”了。然后我们发现,出口运动过程中,假设出口目前走到......
  • js 传递汉字 乱码_JavaScript 字符串反转乱码问题解决
    https://blog.csdn.net/weixin_36483301/article/details/113451892emoji表情和非常用字实际解决中文编码问题,可以通过解码解决js中使用decodeURL即可解决......
  • Atcoder题解:Agc013_e
    我们考虑转化题意,一个合法的将\(1\simN\)划分成长度依次为\(a_1,a_2,\cdotsa_k\)的小区间,对答案的贡献为\(a_1^2a_2^2\cdotsa_k^2\)。化贡献为方案数,我们在每个长度为\(a_i\)的小区间内放置两个独立的标记,每个合法的划分方案对放置标记方案种数的贡献恰好是其对最终答......
  • CF题解
    D.ABGraph2000构造https://codeforces.com/problemset/problem/1481/D题解:由于只有两种边,我们可以枚举较小结构的特性并循环来构造整体解。对于任意两个点,[u->v,v->u]只有4种情况,对于[1,1],[0,0]直接得解,可以循环这个环来构造回文,否则[1,0],[0,1],注意到当所需回文为odd长时,......
  • abc249_f Ignore Operations 题解
    IgnoreOperations题意Takahashi有一个整数\(x\),初始\(x=0\)。有\(n\)次操作。第\(i\)次操作用两个整数\(t_i,y_i\)描述:如果\(t_i=1\),将整数\(x\)替换为\(y_i\)。如果\(t_i=2\),将整数\(x\)替换为\(x+y_i\)。Takahashi可以跳过其中至多\(K\)......
  • TJOI 2015 概率论 题解
    TJOI2015概率论题解题意求\(n\)个点随机生成的有根二叉树(所有互不同构的二叉树出现情况等概率)的叶子节点数的期望值。题解70答案显然是\(\dfrac{g(n)}{f(n)}\),\(g(n)\)是\(n\)个点为所有二叉树的叶子总数,\(f(n)\)是\(n\)个点能生成的二叉树数。一棵树可以用左......
  • abc249_d Index Trio 题解
    IndexTrio题意给定长度为\(n\)的整数序列\(a=(a_1,a_2,\dots,a_n)\)。请你求出有多少个整数三元组\((i,j,k)\)满足:\(1\leqslanti,j,k\leqslantN\)\(\frac{a_i}{a_j}=a_k\)数据范围\(1\leqslantn,a_i\leqslant2\times10^5\)思路转变式子:\(......
  • Ubuntu系统硬盘安装到其他的电脑上,网络连接不上问题解决
    把Ubuntu系统硬盘安装到其他的电脑上,网络连接不了在一台i5电脑上安装好ubuntu18.04后,把该系统磁盘安装到另外一台i5电脑上。系统可以成功启动,但是不能正常上网。解决办法如下:1)用下面这个命令查看本台电脑上可用的网络接口$ifconfig-a#查看可用的网络接口$iplinks......
  • 题解:【ABC298G】Strawberry War
    题目链接场上被F干碎了,没看见这个典题。原题差不多是这个吧......