zoukankan      html  css  js  c++  java
  • 【题解】Atcoder AGC#03 E-Sequential operations on Sequence

      仙题膜拜系列...首先我们可以发现:如果在截取了一段大的区间之后再截取一段小的区间,显然是没有什么用的。所以我们可以将操作序列变成单调递增的序列。

      然后怎么考虑呢?启示:不一定要考虑每一个数字出现的次数——我们还可以计算每一段完整的序列出现的次数。如果我们求出第 (i) 次操作过后产生的序列在答案中共出现了 (rec[i]) 次,那么第 (i - 1) 次操作过后产生的序列必然在答案中出现了 (frac{len[i]}{len[i - 1]} * rec[i]) 次。可是这样还会剩下(rec[i]) 段 (len[i] mod len[i - 1]) 的小区间。我们可以考虑如何统计这一段小区间中出现了哪些完整的序列。

      由于要统计在这段小区间中出现了哪些完整的序列,我们可以找到操作序列中第一个长度小于它的位置(pos)。那么此时这段小区间中会有 (frac{nowlen}{len[pos]}) 段长度为 (len[pos]) 的完整区间。显然这是一个递归求解的问题,而一个数最多取模 log 次的性质保证我们最多会递归 log 次。如果最后剩下的区间比第一个小区间还要小,那么我们可以直接知道对于那些数字的出现做出了贡献,维护差分序列区间加一下就好了。

      **启示:可以转化一下思路,不一定要计算每个数字的贡献,而可以从后往前递推出每段序列出现的次数,将一段序列看作一个整体。而一个数取模最多不会超过 log 次的限制也可以保证递归的次数。

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 1000000
    #define int long long
    int n, Q, m;
    int rec[maxn], len[maxn], ans[maxn]; 
    
    int read()
    {
        int x = 0, k = 1;
        char c; c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    void Solve(int x, int t)
    {
        if(!x) return;
        int pos = upper_bound(len + 1, len + 1 + m, x) - len - 1;
        if(!pos) { ans[1] += t; ans[x + 1] -= t; }
        else
        {
            rec[pos] += (x / len[pos]) * t; 
            Solve(x % len[pos], t);
        }
    }
    
    signed main()
    {
        n = read(), Q = read(); len[++ m] = n;
        for(int i = 1; i <= Q; i ++)
        {
            int x = read();
            while(m && len[m] >= x) m --;
            len[++ m] = x;
        }
        rec[m] = 1;
        for(int i = m; i > 1; i --)
        {
            rec[i - 1] += rec[i] * (len[i] / len[i - 1]);
            Solve(len[i] % len[i - 1], rec[i]);
        }
        ans[1] += rec[1], ans[len[1] + 1] -= rec[1];
        for(int i = 1; i <= n; i ++)
        {
            ans[i] += ans[i - 1];
            printf("%lld ", ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    hdu2846 Repository
    Ajax:js自执行函数、jsonp、cros
    python读写Excel文件--使用xlrd模块读取,xlwt模块写入
    CentOS上快速安装saltstack
    Django_Form表单补充
    前端基础之Bootstrap介绍
    前端基础之jquery练习
    前端基础之Http协议
    Django_随机验证码
    dpkg --add-architecture i386 && apt-get update && > apt-get install wine32
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/9823033.html
Copyright © 2011-2022 走看看