1. 程式人生 > >codeforces 900D(組合數學+剪枝)

codeforces 900D(組合數學+剪枝)

題目連結:http://codeforces.com/problemset/problem/900/D

數列的最大公因數為x則所有的ai均可以由x表示於是若有這樣的陣列則y%x==0。陣列可以分成多個x,於是可以把此題轉化成將y/x個x放進m個箱子裡(不允許有空箱子),於是這道題便轉化成了經典的組合數學問題方案數為C(y/x-1,m-1)把m從2一直疊加到y/x-1於是總共的方案數變化成了2^(y/x-1)-1。但是這樣子會存在非法的序列例如當x=3,y=12相當於4個3,在這裡若直接拿上述方法做會出現6,6這樣的方案數,此序列的最大公因數將不再是3而是6所以要減去這樣的方案數。可以發現產生這樣的情況是因為m為y/x的因子於是減去當m為y/x的因子的情況以即可。在這裡注意要剪枝不然會超時!

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
using namespace std;
typedef long long int LL;
const int mod=1e9+7;
const int maxn=100;
LL num[maxn]={};
int x,y,cnt=0;
map<int,int>vis;   //剪枝遇到相同的y/x則直接返回即可
LL num_pow(LL a,LL k){
    LL res=1;
    for(;k;k>>=1){
        if(k&1) res=(res*a)%mod;
        a=(a*a)%mod;
    }
    return res;
}
LL dfs(LL mid){
    if(mid==1) return 1;
    LL ans=(num_pow(2,mid-1)-1+mod)%mod;
    if(vis.count(mid)) return vis[mid];
    for(int i=0;i<cnt && num[i]*num[i]<=mid;i++)if(mid%num[i]==0){
        ans=(ans-dfs(mid/num[i])+mod)%mod;
        if(num[i]*num[i]!=mid) ans=(ans-dfs(num[i])+mod)%mod;
    }
    vis[mid]=ans;
    return ans;
}
int main()
{
    while(scanf("%d%d",&x,&y)==2){
        vis.clear();cnt=0;
        memset(num,0,sizeof(num));
        if(y%x!=0){
            printf("0\n");
            continue;
        }
        for(int i=2;i*i<=y/x;i++)if(y/x%i==0)//提取全部的因子
            num[cnt++]=i;
        printf("%lld\n",dfs(y/x));
    }
    return 0;
}


相關推薦

codeforces 900D(組合數學+剪枝)

題目連結:http://codeforces.com/problemset/problem/900/D 數列的最大公因數為x則所有的ai均可以由x表示於是若有這樣的陣列則y%x==0。陣列可以分成多個x,於是可以把此題轉化成將y/x個x放進m個箱子裡(不允許有空箱子),於是

Codeforces Round #439 (Div. 2) Problem C (Codeforces 869C) - 組合數學

note als 9.png fig fine 連接 time mod reac — This is not playing but duty as allies of justice, Nii-chan! — Not allies but j

Codeforces 294C 組合數學

pan bsp nbsp clas style ces for ORC code 題意 給出一列燈,初始有一些點亮的燈,每次只能點亮與已經點亮的燈相鄰的燈,問點亮所有燈的方案有多少種 分析 Codeforces 294C 組合數學

CodeForces 407C 組合數學(詳解)

class 這樣的 double type 合數 void 題解 如何 const 題面:   http://codeforces.com/problemset/problem/407/C   一句話題意:給一個長度為n的序列g,m次操作,每次操作(l,r,k)表示將g

CodeForces 785D Anton and School - 2 組合數學

school log cer sin 位置 mem cin typedef pair 題意: 給你一串括號 問你有多少種匹配的子串 就是前半部分都是‘(‘ 後半部分都是‘)‘的子串 思路: 首先我們預處理 當前位置之前有多少左括號 和 當前位置之後有多少右括

Codeforces 451 E. Devu and Flowers(組合數學,數論,容斥原理)

傳送門 解題思路: 假如只有 s 束花束並且不考慮 f ,那麼根據隔板法的可重複的情況時,這裡的答案就是 假如說只有一個 f 受到限制,其不合法時一定是取了超過 f 的花束 那麼根據組合數,我們仍然可以算出其不合法的解共有: 最後,由於根據容斥,減兩遍的東西要加回來,那麼含有偶數個 f 的項

codeforces EC52 div2E. Side Transmutations(組合數學

題意 給定一個字符集的大小 ∣ A ∣

Codeforces 1060F Shrinking Tree - 動態規劃 - 組合數學

題目傳送門   傳送門I   傳送門II   傳送門III 題目大意   給定一棵$n$個點的帶標號樹,不斷執行以下操作: 等概率選取一條邊 刪掉這條邊的它的兩個端點 新建一個點和之前與這兩個點鄰接的點連邊,它的標號從這兩個被刪去的點中等概率選取。

Codeforces 840C On the Bench - 動態規劃 - 組合數學

題目傳送門   傳送門I   傳送門II   傳送門III 題目大意   給定$n$個數,我們認為它們互不相同,即使它們數值上相等,問存在多少排列方式,使得任意兩個相鄰位置上的數的乘積不是完全平方數。   顯然一個正整數$x$可以被表示為$d_{1}\cdot s_{1}^

*【CodeForces - 214D 】Numbers (dp,組合數學

題幹: Furik loves writing all sorts of problems, especially such that he can't solve himself. You've got one of his problems, the one Furik gave to

Codeforces 559C Gerald and Giant Chess【組合數學】【DP】

LINK 題目大意 有一個wxh的網格,上面有n個黑點,問你從(1,1)走到(w,h)不經過任何黑點的方案數 思路 考慮容斥 先把所有黑點按照x值進行排序方便計算 \(dp_{i}\)表示從起點走到第i個黑點不經過任何的黑點的方案數 然後\(dp_{i}=C(x_i+y_i-2,x_i-1)-\s

Codeforces Round #519 by Botan Investments F. Make It One (組合數學+dp)

題目連結:F 題意:給一串數字,讓你從中找出最少的數字,使得它們的最大公約數為1。   參考連結:https://blog.csdn.net/Link_Ray/article/details/83627570   題解:由2 * 3 * 5 * 7 * 1

CodeForces - 288B】Polo the Penguin and Houses (組合數學+Purfer序列)

Little penguin Polo loves his home village. The village has n houses, indexed by integers from 1 to n. Each house has a plaque contai

CodeForces - 340C】Tourist Problem (組合數學

Iahub is a big fan of tourists. He wants to become a tourist himself, so he planned a trip. There are n destinations on a straight road th

組合數學dp】Educational Codeforces Round 51 (Rated for Div. 2) D. Bicolorings

Step1 Problem: 給你 2*n 的矩陣,你可以對於每個格子填塗黒色或者白色,如果相鄰顏色一樣看成同一塊,問你塗完後恰好有 k 塊的方案數。 資料範圍: 1 <= n <= 1000, 1 <= k <= 2n. Step2

Codeforces Round #338 (Div. 2)D. Multipliers【費馬小定理+組合數學

D. Multipliers time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output

CodeForces 37 D.Lesson Timetable(組合數學+dp)

Description 有m個教室,第i個教室最多可以容納yi人上課,初始狀態第i個教室有xi人,a教室的人可以移動到b教室(a≤b),問移動後有多少種可能方案,結果模109+7 Input 第一

codeforces 893E Counting Arrays (組合數學)

//C n+m-1 m; //2^(y-1); #include<stdio.h> #include<string.h> #include<math.h> #include<vector> using namespace std; vector<int

CodeForces 140 E.New Year Garland(組合數學+dp)

Description n排,第i排li個位置,現在要給所有位置用m種顏色上色,需要滿足: 1.每一排相鄰位置不同色 2.相鄰排所用顏色集不同 問方案數,結果模p Input 第一行三個整數

CodeForces 571A Lengthening Sticks (組合數學

#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #def