zoukankan      html  css  js  c++  java
  • 牛客练习赛25 C 再编号

    解题思路

    我们先来观察一下题目中给出的公式

    $$a'_i=(sum_{j=1}^na_j)-a_i$$

    通过这个公式推一下经过再编号后的序列的总和,因为我们推出这个和之后可以进行下一次计算。

    $$sum_{i=1}^na'_i=sum_{i=1}^n((sum_{j=1}^na_j)-a_i)$$

    变形一下

    $$sum_{i=1}^na'_i=n imes (sum_{j=1}^na_j)-sum_{i=1}^na_i$$

    $$sum_{i=1}^na'_i=(n-1) imes sum_{i=1}^na_i$$

    emmmm,这个结论貌似很有用的样子,我们可以通过上面的推导预处理处每一次变化后整个序列的总和。

    在观察一下原来的序列,每一次再编号他们的每个数和第一个数的差的绝对值是不变的。并且在奇数次的变化后为$a_1-a_j$,偶数次变化后是$a_j-a_1$。

    既然是这样子,那我们就可以再通过之前预处理的总和在处理出每一次改变后的第一个值。通过这个值我们可以$O(1)$的对每一个位置上的数值进行询问。

    这样的话总时间复杂度是$O(t)$的

    代码看这里

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <vector>
    using namespace std;
    #define LL long long
    #define mod int(1e9+7)
    LL a[100010],n,m,sum[100100];
    LL ans[100001][2],num;
    int main()
    {
        LL x,t;
        scanf("%lld%lld%lld",&n,&m,&a[1]);
        num=a[1];
        for(int i=2;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            num+=a[i];
            sum[i]=a[1]-a[i];
        }
        ans[0][1]=a[1];
        for(int i=1;i<=100001;i++)
        {
            ans[i][1]=((num-a[1])+2*mod)%mod;
            a[1]=ans[i][1];
            num=(num*(n-1))%mod;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%lld%lld",&x,&t);
            if(t%2!=0)printf("%lld
    ",(ans[t][1]+sum[x]+mod)%mod);
            else printf("%lld
    ",(ans[t][1]-sum[x]+mod)%mod);
        }
    }
  • 相关阅读:
    python引用.py文件
    推荐系统之矩阵分解 转载 特别好
    数据挖掘之一元线性回归 python代码
    system服务文件讲解 转载
    bin sbin /usr/bin /usr/sbin区别 转载
    linux设置部门(或者学生部门)的共享目录
    Error establishing a database connection wordpress网站出现这个问题centos7的
    tomcat的java项目部署位置
    MAMP PRO教程
    MAMP使用简单教程
  • 原文地址:https://www.cnblogs.com/bljfy/p/9532789.html
Copyright © 2011-2022 走看看