AtCoder ABC 156F Modularness

题目链接:https://atcoder.jp/contests/abc156/tasks/abc156_f

题目大意

  给定$k$个数:$d_0,d_1,...,d_{k - 1}$。

  再给出$q$条询问,每条询问给出$n, x, m$三个数,并按以下规则生成$a_0,a_1,...,a_{n - 1}$序列:

  $$
    \begin{eqnarray}
      a_j = \begin{cases}x & ( j = 0 ) \\ a_{j - 1} + d_{(j - 1)~\textrm{mod}~k} & ( 0 < j \leq n - 1 )\end{cases}
    \end{eqnarray}
  $$

  求满足$(a_j~\textrm{mod}~m) < (a_{j + 1}~\textrm{mod}~m)$的$j$的个数。

分析

  首先,先让$d_i = d_i~\textrm{mod}~m$,容易看出,这并不会影响答案。
  设$ltcnt$为满足$(a_j~\textrm{mod}~m) < (a_{j + 1}~\textrm{mod}~m)$的$j$的个数。
  设$gtcnt$为满足$(a_j~\textrm{mod}~m) > (a_{j + 1}~\textrm{mod}~m)$的$j$的个数。
  设$eqcnt$为满足$(a_j~\textrm{mod}~m) == (a_{j + 1}~\textrm{mod}~m)$的$j$的个数。
  题目要求的是$ltcnt$,但好像不太好求。反过来想一想,我们如果求出了$gtcnt$和$eqcnt$,$ltcnt$不就出来了吗!
  对于$eqcnt$,即求$d_{j~\textrm{mod}~k} == 0$的个数。
  对于$gtcnt$,如果$(a_j~\textrm{mod}~m) > (a_{j + 1}~\textrm{mod}~m)$成立,那么必然有$(\frac{a_j}{m} + 1) == \frac{a_{j + 1}}{m}$,因此只要计算一下$\frac{a_0}{m}$到$\frac{a_{n - 1}}{m}$增长了多少即可。

代码如下

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 /*-------------------Define Start-------------------*/
  5 typedef bool BL;                        // 布尔类型
  6 typedef char SB;                        // 有符号1字节,8位
  7 typedef unsigned char UB;                // 无符号1字节,8位
  8 typedef short SW;                        // 有符号短整型,16位
  9 typedef unsigned short UW;                // 无符号短整型,16位
 10 typedef long SDW;                        // 有符号整型,32位
 11 typedef unsigned long UDW;               // 无符号整型,32位
 12 typedef long long SLL;                    // 有符号长整型,64位
 13 typedef unsigned long long ULL;            // 无符号长整型,64位
 14 typedef char CH;                        // 单个字符
 15 typedef float R32;                        // 单精度浮点数
 16 typedef double R64;                        // 双精度浮点数
 17 
 18 #define Rep(i, n) for (register SDW i = 0; i < (n); ++i)
 19 #define For(i, s, t) for (register SDW i = (s); i <= (t); ++i)
 20 #define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i)
 21 #define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 22 #define ms0(a) memset(a,0,sizeof(a))
 23 #define msI(a) memset(a,0x7f,sizeof(a))
 24 #define LOWBIT(x) ((x)&(-x))
 25 
 26 #define MP make_pair
 27 #define PB push_back
 28 #define ft first
 29 #define sd second
 30 #define ALL(x) x.begin(),x.end()
 31 
 32 #define pr(x) cout << #x << " = " << x << "  "
 33 #define prln(x) cout << #x << " = " << x << endl
 34 
 35 const ULL mod = 1e9 + 7;                //常用模数(可根据题目需要修改)
 36 const ULL inf = 0x7fffffff;                //用来表示无限大
 37 const ULL infLL = 0x7fffffffffffffffLL;    //用来表示无限大
 38 
 39 // 重载<<操作符,用来打印vector 
 40 template < typename T >
 41 ostream& operator<< (ostream& out, vector< T > vec) {
 42     foreach(i, vec) {
 43         if(i != vec.begin()) {
 44             out << " ";
 45         }
 46         out << *i;
 47     }
 48     return out;
 49 }
 50 /*-------------------Define End-------------------*/
 51 
 52 const UDW maxN = 5e3 + 7;
 53 SDW k, q;
 54 SLL d[maxN], dm[maxN];
 55 SLL n, x, m;
 56 SLL eqcnt;    // 记录 a[i] % m == a[i+1] % m 的个数 
 57 SLL gtcnt;    // 记录 a[i] % m > a[i+1] % m 的个数 
 58 SLL ltcnt;    // 记录 a[i] % m < a[i+1] % m 的个数 
 59 SLL firstA; // a[0]
 60 SLL lastA;    // a[n-1]
 61 SLL ans;
 62 
 63 void input(){
 64     eqcnt = gtcnt = ltcnt = ans = 0;
 65     cin >> n >> x >> m;
 66 }
 67 
 68 void solve(){
 69     firstA = lastA = x;
 70     
 71     Rep(i, k) {
 72         dm[i] = d[i] % m;
 73         lastA += ((n - 1) / k) * dm[i]; 
 74         if(i < (n - 1) % k) {
 75             lastA += dm[i];
 76         }
 77         gtcnt += lastA / m;
 78         lastA %= m;
 79     }
 80     
 81     Rep(i, k) {
 82         if(dm[i] == 0) {
 83             eqcnt += (n - 1) / k;
 84             if(i < (n - 1) % k) {
 85                 ++eqcnt;
 86             }
 87         }
 88     }
 89     
 90     gtcnt -= firstA / m;
 91     ltcnt = n - 1 - eqcnt - gtcnt;
 92     
 93     ans = ltcnt;
 94 }
 95 
 96 void output(){
 97     cout << ans << endl;
 98 }
 99 
100 int main() {
101     cin >> k >> q;
102     Rep(i, k) {
103         cin >> d[i];
104     }
105     while(q--) {
106         input();
107         solve();
108         output();
109     }
110     return 0;
111 }
View Code

 

posted @ 2020-03-07 10:22  梦樱羽  阅读(292)  评论(0编辑  收藏  举报
Live2D