HDU 5768 Lucky7 中国剩余定理
2016-07-29 19:50
302 查看
转载声明:http://blog.csdn.net/acdreamers/article/details/8050018 (模板)
题意:给你一段区间的,要求能被7整除的个数,然后给你n个条件, 其中的得到所有数不能满足 给出的 x%x1=r1, x%x2=r2。。。等条件.输出个数.
个人感想:
这是一道中国剩余定理题目, 我当时比赛的时候我也不会做..我只是知道有这样的公式..就是可以求出满足的所有解,但我不知道是什么鬼..然后大牛告诉我了是中国剩余定理.我特么就半桶水的东西,我感觉怎么也不会考…然后之前都没学下去,真是瞎鸡巴搞了. 我是知道要用到容斥,算了..不说心酸史, 我直接套上链接的模板去做的,在统计区间中整数的数组的时候要注意 最左区间要-1, 和求那个前缀和一样,否则就除问题了,我坑了一个多小时在那.默哀.. 例如 求 7<= 7t<=9;满足的条件中 t的个数, 这时候答案是0的! 因为是向下取整导致这样的问题,所以求t时 应该 7-1<7t<=9 这样才求出来是1! 而且要注意 t能满足0的情况,这样的区间相减是不包括0的!!
题意:给你一段区间的,要求能被7整除的个数,然后给你n个条件, 其中的得到所有数不能满足 给出的 x%x1=r1, x%x2=r2。。。等条件.输出个数.
个人感想:
这是一道中国剩余定理题目, 我当时比赛的时候我也不会做..我只是知道有这样的公式..就是可以求出满足的所有解,但我不知道是什么鬼..然后大牛告诉我了是中国剩余定理.我特么就半桶水的东西,我感觉怎么也不会考…然后之前都没学下去,真是瞎鸡巴搞了. 我是知道要用到容斥,算了..不说心酸史, 我直接套上链接的模板去做的,在统计区间中整数的数组的时候要注意 最左区间要-1, 和求那个前缀和一样,否则就除问题了,我坑了一个多小时在那.默哀.. 例如 求 7<= 7t<=9;满足的条件中 t的个数, 这时候答案是0的! 因为是向下取整导致这样的问题,所以求t时 应该 7-1<7t<=9 这样才求出来是1! 而且要注意 t能满足0的情况,这样的区间相减是不包括0的!!
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ //#define OUT #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define Clear(x) memset(x,0,sizeof(x)) const int INF=0x3f3f3f3f; typedef long long LL; const int maxn=20; LL n,x,y; int T; LL a[maxn],p[maxn]; LL gcd(LL a,LL b) { return b? gcd(b, a % b) : a; } void extend_Euclid(LL a, LL b, LL &x, LL &y) { if(b == 0) { x = 1; y = 0; return; } extend_Euclid(b, a % b, x, y); LL tmp = x; x = y; y = tmp - (a / b) * y; } LL Inv(LL a, LL b) { LL d = gcd(a, b); if(d != 1) return -1; LL x, y; extend_Euclid(a, b, x, y); return (x % b + b) % b; } bool Merge(LL a1, LL m1, LL a2, LL m2, LL &a3, LL &m3) { LL d = gcd(m1, m2); LL c = a2 - a1; if(c % d) return false; c = (c % m2 + m2) % m2; m1 /= d; m2 /= d; c /= d; c *= Inv(m1, m2); c %= m2; c *= m1 * d; c += a1; m3 = m1 * m2 * d; a3 = (c % m3 + m3) % m3; return true; } LL solve(int n) { LL a1 = 0; LL m1 = 7; int tmp=0; while(n) { if(n&1) { LL a2 = a[tmp]; LL m2 = p[tmp]; LL m3, a3; if(!Merge(a1, m1, a2, m2, a3, m3)) return -1; a1 = a3; m1 = m3; } tmp++; n>>=1; } a1=(a1 % m1 + m1) % m1; LL res=0; res+=((y-a1)/m1 -(x-a1-1)/m1); if(a1>=x&&a1<=y)res++;//至于为什么要特殊判断 主要我们求出来的时候是( x<=a1+mt<=y,那么两边互相消去之后的t的个数是不包括0的,所以要特判一下. return res; } LL getT(int n) { int res=0; while(n) { if(n&1)res++; n>>=1; } return res; } LL f(LL x) { if(x%2)return 1; return -1; } int main() { #ifdef OUT freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout); #endif scanf("%d",&T); for(int cas=1; cas<=T; cas++) { scanf("%I64d%I64d%I64d",&n,&x,&y); LL ans=(y/7-(x-1)/7); for(int i=0; i<n; i++) { scanf("%I64d%I64d",&p[i],&a[i]); } LL tmp=0; LL limited=1<<n; for(int i=1; i<limited; i++) { int tot=getT(i); LL t=solve(i); tmp+=f(tot)*t; } printf("Case #%d: %I64d\n",cas,ans-tmp); } return 0; }
相关文章推荐
- Sublime软件的安装
- NYOJ-722 数独
- HDOJ 2612 Find a way
- 二分图判定
- hd 2717 Catch That Cow
- 【代码笔记】HTML+CSS+JavaScript实现密码输入框显示文字
- Linux mint/Ubuntu 如何修改主机名(亲测有效)
- 后缀数组 poj 3261
- git 放弃本地修改 强制更新
- Squirrel: 通用SQL、NoSQL客户端
- sdut oj1252 进制转换(栈)
- HDU--1233最小生成树之kruskal算法
- 用c++编写一段完整代码,要求判断一个进程(例如qq.exe)是否存在,若存在,输出存在,不存在就输出不存在。
- 多项式求和
- SVD 详解 与 spark实战
- 当浏览器窗体改变时,div跟着变动方法
- Laravel 5.2中记录运行时 SQL
- 0728linux基础内容小记
- 文章标题
- 原生js实现随着滚动条滚动,导航会自动切换的效果