zoukankan      html  css  js  c++  java
  • HDU 5768 Lucky7 (中国剩余定理+容斥)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5768

    给你n个同余方程组,然后给你l,r,问你l,r中有多少数%7=0且%ai != bi.

    比较明显的中国剩余定理+容斥,容斥的时候每次要加上个(%7=0)这一组。

    中间会爆longlong,所以在其中加上个快速乘法(类似快速幂)。因为普通的a*b是直接a个b相加,很可能会爆。但是你可以将b拆分为二进制来加a,这样又快又可以防爆。

      1 //#pragma comment(linker, "/STACK:102400000, 102400000")
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <ctime>
     10 #include <list>
     11 #include <set>
     12 #include <map>
     13 using namespace std;
     14 typedef long long LL;
     15 typedef pair <int, int> P;
     16 const int N = 1e5 + 5;
     17 LL a[17] , b[17], fuck = 1e18;
     18 
     19 LL Fmul(LL a , LL n , LL mod) { //快速乘法
     20     LL res = 0;
     21     while(n) {
     22         if(n & 1) {
     23             res = (res + a) % mod;
     24         }
     25         a = a * 2 % mod;
     26         n >>= 1;
     27     }
     28     return res;
     29 }
     30 
     31 LL exgcd(LL a , LL b , LL &x , LL &y) {
     32     LL res = a;
     33     if(!b) {
     34         x = 1;
     35         y = 0;
     36     }
     37     else {
     38         res = exgcd(b , a % b , x , y);
     39         LL temp = x;
     40         x = y;
     41         y = temp - a / b * y;
     42     }
     43     return res;
     44 }
     45 
     46 LL CRT(LL a[] , LL m[] , LL n) {
     47     LL M = 1 , res = 0;
     48     for(LL i = 1 ; i <= n ; i++) {
     49         M = M * m[i];
     50     }
     51     for(LL i = 1 ; i <= n ; i++) {
     52         LL x , y , Mi = M / m[i];
     53         exgcd(Mi , m[i] , x , y);
     54         x = (x % m[i] + m[i]) % m[i];
     55         res = (res + Fmul(x * a[i] % M , Mi , M) + M) % M;
     56     }
     57     if(res < 0) 
     58         res += M;
     59     return res;
     60 }
     61 
     62 LL Get(LL n, LL x, LL y) {
     63     if(x > n)
     64         return 0;
     65     else {
     66         n -= x;
     67         return (LL)(1 + n / y);
     68     }
     69 }
     70 
     71 int main()
     72 {
     73     int t, n;
     74     LL l , r , md[17], di[17];
     75     scanf("%d", &t);
     76     for(int ca = 1; ca <= t; ++ca) {
     77         scanf("%d %lld %lld", &n, &l, &r);
     78         di[1] = 7, md[1] = 0;
     79         for(int i = 1; i <= n; ++i) {
     80             scanf("%lld %lld", a + i, b + i);
     81         }
     82         LL res1 = 0, res2 = 0;
     83         int limit = (1 << n) - 1;
     84         for(int i = 1; i <= limit; ++i) {
     85             int temp = i, index = 1;
     86             LL mul = 7;
     87             for(int j = 1 ; temp ; ++j) {
     88                 if(temp & 1) {
     89                     di[++index] = a[j];
     90                     md[index] = b[j];
     91                     mul *= a[j];
     92                 }
     93                 temp >>= 1;
     94             }
     95             if(index % 2) {
     96                 res1 -= Get(l - 1, CRT(md, di, index), mul);
     97                 res2 -= Get(r, CRT(md, di, index), mul);
     98             }
     99             else {
    100                 res1 += Get(l - 1, CRT(md, di, index), mul);
    101                 res2 += Get(r, CRT(md, di, index), mul);
    102             }
    103         }
    104         printf("Case #%d: %lld
    ",ca, r/7 - (l-1)/7 - (res2 - res1));
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    C++怎么实现线程安全
    Linux内核之进程地址空间
    Linux内核之内存管理
    内存管理之内存寻址
    Linux内核初探
    进程间通信
    下拉列表控件实例 ComboBoxControl
    数据表格控件 DataGridControl
    8 种百度云高速下载,你值得拥有
    10 快好用的下载工具,终于和迅雷说拜拜了
  • 原文地址:https://www.cnblogs.com/Recoder/p/5726300.html
Copyright © 2011-2022 走看看