zoukankan      html  css  js  c++  java
  • 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}$序列:

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

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

    分析

      首先,先让$d_i = d_i~ extrm{mod}~m$,容易看出,这并不会影响答案。
      设$ltcnt$为满足$(a_j~ extrm{mod}~m) < (a_{j + 1}~ extrm{mod}~m)$的$j$的个数。
      设$gtcnt$为满足$(a_j~ extrm{mod}~m) > (a_{j + 1}~ extrm{mod}~m)$的$j$的个数。
      设$eqcnt$为满足$(a_j~ extrm{mod}~m) == (a_{j + 1}~ extrm{mod}~m)$的$j$的个数。
      题目要求的是$ltcnt$,但好像不太好求。反过来想一想,我们如果求出了$gtcnt$和$eqcnt$,$ltcnt$不就出来了吗!
      对于$eqcnt$,即求$d_{j~ extrm{mod}~k} == 0$的个数。
      对于$gtcnt$,如果$(a_j~ extrm{mod}~m) > (a_{j + 1}~ extrm{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
  • 相关阅读:
    成为JAVA(高级)工程师
    JVM的内存区域划分以及垃圾回收机制
    XML
    String.valueOf
    JAVA书籍(2)
    JAVA书籍(1)
    深入JAVA线程池
    FileWriter与BufferedWriter
    获取下拉框的文本或值
    删除字符串最后一个字符的几种方法
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/12432881.html
Copyright © 2011-2022 走看看