hihocoder 1246 王胖浩与环
生活随笔
收集整理的這篇文章主要介紹了
hihocoder 1246 王胖浩与环
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
給出一個環,環上有n(<=2000)個數字(<=5e7),然后將這個環分成1~n個連續序列,各個序列和之間的最大公因數。
?
題解:
我一開始想到的是二分,然后對于二分就會想怎么check,那么可以枚舉這n個數和的因數,因為答案一定在這里面,然后就會找出對于每個因數可以分成的段數,但是這個并不滿足單調性QAQ,但提供了一定的思路
考慮從大到小枚舉因數,然后對于這個因數分成盡量多的部分,因為不難知道如果a % x == 0,(a + b) % x == 0 那么b % x == 0,因為這樣就可以一直貪心找最大的因數。
然后現在的問題就是考慮環的情況,一般的做法是斷環為鏈,枚舉起點到終點找出有多少段%x == 0,但是可以稍微變一下形,如果pre[i] % x == y, pre[j] % x == y,那么i ~ j這一段%x為0,那么(1 ~ i) + (j+1 ~ n) % x == 0,那么現在的問題就是統計余數出現最多的次數,就完美處理了環的情況。
?
代碼:
?
#include <bits/stdc++.h> using namespace std;const int N = 4e3 + 7; #define LL long long vector <LL> num; int n; LL pre[N];int main () {scanf ("%d", &n);for (int i = 1; i <= n; ++i) {int x;scanf ("%d", &x);pre[i] = pre[i-1] + x;}for (LL i = 1; i * i <= pre[n]; ++i) {if (pre[n] % i == 0) {if (i * i == pre[n]) {num.push_back(i);continue;}num.push_back(i);num.push_back(pre[n] / i);}}sort (num.begin(), num.end());int K = 1;for (int i = num.size() - 1; i >= 0; --i) {int maxi = 0;vector <LL> v;for (int j = 1; j <= n; ++j) v.push_back(pre[j] % num[i]);sort (v.begin(), v.end());int pre = 0;for (int j = 0; j < v.size(); ++j) {if (v[j] == v[j+1] && j != v.size()-1) continue;maxi = max (maxi, j - pre + 1);pre = j + 1;}while (K <= maxi) {printf ("%lld\n", num[i]);++K;}}return 0; }
總結:
這種求因數的題,并且數的范圍不大,可以直接暴力枚舉因數。。。。。。還有注意的是公式的變換~
轉載于:https://www.cnblogs.com/xgtao/p/6014657.html
總結
以上是生活随笔為你收集整理的hihocoder 1246 王胖浩与环的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php基础 快速入门文档,快速入门 -
- 下一篇: 论文阅读: (ICDAR2021 海康威