码迷,mamicode.com
首页 > 其他好文 > 详细

CF1484B Restore Modulo 题解

时间:2021-04-09 13:14:58      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:意义   mat   排除   sts   play   putc   text   pre   ref   

\(\text{Description}\)

给定长度为 \(n\) 的序列 \(a\),求是否存在最大的 \(m\) 使得 \(a\) 在模意义下是等差数列。

\(\text{Solution}\)

首先我们要知道 \(a_i\) 只有可能由以下两个式子推得:

\[a_i=a_{i-1}+c\quad(1) \]

\[a_i=a_{i-1}+c-m\quad(2) \]

若由 \((1)\) 转移来,则说明 \(a_i \ge a_{i-1}\) ,反之则有 \(a_i < a_{i-1}\)

结论:构造差分序列 \(b\)\(b_i=a_i-a_{i-1}\) 若有解,则 \(b\) 中最多只有两个不相同的数字

证明:

考虑分类讨论,若由上述 \((1)\) 转移来。则 \(b_i = c\),反之 \(b_i=c-m\)

特殊地:如果 \(b\) 是常数列,则 \(m\) 可取任何值。

如果 \(\forall i\in[1,n],\exists b_i < 0\) 则无解。

排除上述情况之后就可以来计算 \(m,c\) 的值了:

\(b\) 中不同的两项数字为 \(p,q\) ,则:

\(m = |p|+|q|,c=\max(p,q)\)

自己推下式子就可以证明了。

\(\text{Code}\)

/*If you are full of hope,you will be invincible*/
constexpr int N = 1e5 + 10;
int a[N],b[N],n,T;
std::unordered_map <int,bool> vis;
int num,ans,ans_;
inline void Solve() {
    vis.clear(),num=ans=ans_=0;        
    int mx = -1,tmp[3];
    read(n);
    memset(a,0,sizeof a),memset(b,0,sizeof b);
    for(int i = 1;i <= n;++i) read(a[i]),mx=max(a[i],mx);
    if(n == 1)  return ans = 0,void();
    for(int i = 2;i <= n;++i) b[i-1] = a[i] - a[i-1];//差分
    int num = 0;
    for(int i = 1;i <= n-1;++i) {
         if(!vis[b[i]]) tmp[++num] = b[i],vis[b[i]] = 1;
         if(num == 3) return ans = -1,void();//如果有三个不同的数
    }
    if(num == 1) return ans = 0,void();
    if(tmp[1] < 0 and tmp[2] < 0) return ans = -1,void();
    ans = abs(tmp[1]) + abs(tmp[2]),ans_ = max(tmp[1],tmp[2]);
    if(ans < mx) return ans = -1,void();
}
int main(int argc,const char **argv) {
    read(T);
    while(T--) {
        Solve();
        if(ans == -1 || ans == 0) print(‘\n‘,ans);
        else print(‘ ‘,ans,ans_),STD::putc(‘\n‘); 
    }
    return STD::flush(),0;
}

CF1484B Restore Modulo 题解

标签:意义   mat   排除   sts   play   putc   text   pre   ref   

原文地址:https://www.cnblogs.com/hl-fc/p/14634406.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!