zoukankan      html  css  js  c++  java
  • AGC010

    原题链接

    题意简述

    给出一个由n(n105)个数构成的环,每次可以选择一个位置并从这个数起顺时针依次对每个数-1,-2,-3,…,-n。问能否将所有数全变为0。

    分析

    考虑一次操作对环带来了什么影响。
    (在an后加一个a1来表示数环)
    6,3,5,7,9(,6) -> 5,1,2,3,4(,5)
    5,1,2,3,4(,5) -> 0,0,0,0,0(,0)
    差分后:
    3,2,2,2,3 -> 4,1,1,1,1
    4,1,1,1,1 -> 0,0,0,0,0
    可以看到,一次操作相当于对差分数列(或者说是差分环)的一个位置加上n-1,剩下的位置减去1。那么只要检查原环的差分数列能否全变为0,并且此时和也为0就行了。
    对每一个位置的计算复杂度为O(1),总时间复杂度为O(n)

    实现

    每次操作会使和sum减少 s0=n(n+1)/2,那么总共进行了 k=sum/s0 次操作。如果k不为整数那么不可行。
    差分数列的每个位置要能在数个 +(n1)1 后变为0,否则不可行。
    列式表示为 (ai+1ai)+xi(n1)(kxi)=0,如果任何一个xi不为整数那么不可行。
    最后,如果xik说明此时sum0,不可行。

    代码

    #include <cstdio>
    typedef long long lint;
    int const N=1e5+10;
    int n,a[N];
    int dif[N];
    int main()
    {
        freopen("b.in","r",stdin);
        scanf("%d",&n);
        if(n==1) {printf("YES"); return 0;}
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        a[n+1]=a[1];
        lint s=(lint)n*(n+1)>>1,sum=0;
        for(int i=1;i<=n;i++) sum+=a[i],dif[i]=a[i+1]-a[i];
        if(sum%s!=0) {printf("NO"); return 0;}
        lint k=sum/s,sumX=0;
        for(int i=1;i<=n;i++)
        {
            lint x=(k-dif[i])/n;
            if(x<0 || x*n!=k-dif[i]) {printf("NO"); return 0;}
            sumX+=x;
        }
        if(sumX==k) printf("YES");
        else printf("NO");
        return 0;
    }

    注意

    开longlong!int*int也有可能爆int,要先转成longlong再乘!
    连WA六发…

  • 相关阅读:
    MQ的导出备份
    js中this的使用
    wordpress目录文件结构说明
    css3 rem的用法
    初探Backbone
    call 和 apply使用
    公告栏放honehoneclock和喂小老鼠flash
    什么是好单位与坏单位
    常用正则表达式
    gulp入门教程
  • 原文地址:https://www.cnblogs.com/VisJiao/p/8485773.html
Copyright © 2011-2022 走看看