容斥原理实现的关键在于:组合遍历,即如何遍历2^n种组合。

容斥原理的三种写法:

  • DFS
  • 队列数组
  • 位数组
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
const int maxn = 32000;
bool isPrime[maxn];
int prime[maxn / 4], psize;//线性筛法必须用数组存储现有质数
int p[40], ps;
typedef long long ll;
void init(){
memset(isPrime, 1, sizeof(isPrime));
psize = 0;
for (int i = 2; i < maxn; i++){
if (isPrime[i]){
prime[psize++] = i;
}
for (int j = 0; j < psize&&prime[j] * i < maxn; j++){
isPrime[i*prime[j]] = false;
if (i%prime[j] == 0)
break;
}
}
}
void parse(ll x){
ps = 0;
for (int i = 0;i<psize; i++){
if (x%prime[i] == 0){
p[ps++] = prime[i];
while (x%prime[i] == 0)x /= prime[i];
if (x == 1)return;
}
}
if (x>1){
p[ps++] = x;
}
}
ll dfs(ll ind, ll n, ll x){
ll s = 0;
for (int i = ind; i < ps; i++){
s += n / p[i] - dfs(i + 1, n / p[i], x);
}
return s;
}
ll huzhi(ll n, ll x){
return n - dfs(0, n, x);
}
int main(){
freopen("in.txt", "r", stdin);
init();
int T; scanf("%d", &T);
int caseid = 1;
ll A, B, N;
while (T--){
cin >> A >> B >> N;
ll ans;
if (N == 1){
ans = B - A+1;
}
else{
parse(N);
ans = huzhi(B, N) - huzhi(A-1, N);
}
printf("Case #%d: %I64d\n", caseid++, ans);
}
return 0;
}

队列数组法实现容斥原理:

__int64 haha(__int64 m) //用队列数组实现容斥原理
{
__int64 que[10000], t = 0, sum = 0;
que[t++] = -1;
for (int i = 0; i < num; i++) {
int k = t;//保存一层
for (int j = 0; j < k; j++)
que[t++] = que[j] * a[i] * (-1);
}
for (int i = 1; i < t; i++)
sum = sum + m / que[i];
return sum;
}

队列数组实现容斥原理的思想就是:让下列元素按顺序进队列:

  • 1=1+空 ----1处理完了
  • 2=2+空
  • 12=2+1 ----2处理完了
  • 3=3+空
  • 13=3+1
  • 23=3+2
  • 123=3+12 ---3处理完了

队列数组需要开辟一个队列来存储过去的元素,浪费空间。但是它对于每种组合,它没有从头开始计算,而是按照一定的顺序在过去基础上计算。借鉴这个思想,位数组不一定每次都需要从头计算,可以通过格雷码来表示位数组,这样每次只变化1位,不需要额外空间,兼具队列数组和位数组的优点。

如何获取变化的那一位呢?记m为第i+1个格雷码,n为第i个格雷码,则mn即为变化的那一位,log2(mn)即得下标。

接下来就可以在上一步的基础上进行加入或移除操作。

hdu4135容斥原理 组合遍历的更多相关文章

  1. poj3904 Sky Code —— 唯一分解定理 + 容斥原理 + 组合

    题目链接:http://poj.org/problem?id=3904 Sky Code Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  2. PHP正则表达式;数组:for()遍历、 foreach ()遍历、each()list()组合遍历;指针遍历

    正则表达式:    1.定界符号        任何字符,一般用  //    2. 模式修正符i        写在定界符外面后面,可不区分大小写    3.preg_replace($reg,&q ...

  3. php两个多维数组组合遍历

    $res = $this->LoanRecord->searchloan($conditions,$columns,$page,$this->num,$user_id); forea ...

  4. HDU 4390 Number Sequence (容斥原理+组合计数)

    HDU 4390 题意: 大概就是这样.不翻译了: Given a number sequence b1,b2-bn. Please count how many number sequences a ...

  5. BZOJ 2839: 集合计数 [容斥原理 组合]

    2839: 集合计数 题意:n个元素的集合,选出若干子集使得交集大小为k,求方案数 先选出k个\(\binom{n}{k}\),剩下选出一些集合交集为空集 考虑容斥 \[ 交集为\emptyset = ...

  6. 【BZOJ 3027】 3027: [Ceoi2004]Sweet (容斥原理+组合计数)

    3027: [Ceoi2004]Sweet Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 71  Solved: 34 Description John ...

  7. HDU4135(容斥原理)

    Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. HDU4135容斥原理

    #include <cstdio> #include <string.h> #include <cmath> using namespace std; #defin ...

  9. php中的循环遍历 foreach list each

    foreach语句遍历数组foreach语句用于循环遍历数组,每进行一次循环,当前数组元素的值就会被赋值给变量value(也可以是其它变量),数组指针会逐一的移动. 代码示例: foreach($ar ...

随机推荐

  1. MiniGUI ial 移植指南

    MiniGUI ial 移植指南 2.1 ial的定义 ial是一个通用的抽象输入接口,可以输入统一的数据的结构,也就是说在MiniGUI的核心代码里输入的数据的格式是固定的,不管输入设备是鼠标 还是 ...

  2. 简明python教程 --C++程序员的视角(七):异常

    当你的程序中出现某些 异常的 状况的时候,异常就发生了.例如,当你想要读某个文件的时候,而那个文件不存在.或者在程序运行的时候,你不小心把它删除了.上述这些情况可以使用异常来处理. 假如你的程序中有一 ...

  3. IDEA的注册

    步骤: license server -> 属性 -> 允许作为程序执行文件 即 chmod 777

  4. 泛泰A870(高通600 cpu 720p) 刷4.4专用中文recovery TWRP2.7.1.1版(三版通刷)

    欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam  (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...

  5. LinkedList剖析

    第1部分 LinkedList介绍 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作. D ...

  6. 关于MFC框架程序中CWinApp::OnIdle

    很早之前就发现,我写的图形引擎在MFC框架程序中的刷帧率始终在60FPS左右.好在自己的程序对刷帧率的要求不是很高,所以一直没有太过纠结此事.直到今天看了别人的程序才发现应该在函数CWinApp::O ...

  7. HTML5 Canvas,WebGL,CSS Shaders,GLSL的暧昧关系 【转】

    HTML5 Canvas,WebGL,CSS Shaders,GLSL的暧昧关系 这篇文章发布于 2011年10月10日,星期一,17:14,归类于 canvas相关. 阅读 58013 次, 今日 ...

  8. Android -- Drawable && Bitmap

    Bitmap转Drawable Bitmap bm=xxx; BitmapDrawable bd=new BitmapDrawable(bm); 因为BtimapDrawable是Drawable的子 ...

  9. Nuget添加新项目的问题

    为已有的几个项目添加了一个nuget package 后,在解决方法中添加了一个新项目,然后想把这个nuget package添加到这个新建的项目中去,可以此时无法添加.     怎么办那? [解决方 ...

  10. 在Foreda8上试安装Apchehttpd-2.4.6.tar.gz

    下文是我边试边做的记录,不保证内容的完整性和正确性. 由于我的Apsire机器是最简安装Foreda8,所以需要安装httpd,熟悉一遍也是很好的嘛. 我从网上搜罗并下载了apchehttpd-2.4 ...