国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

ICPCCamp2017 Day 5 I Coprime Queries(莫比烏斯函數 + 容斥定理 + 二分)

2019-11-08 03:00:54
字體:
來源:轉載
供稿:網友

題意:

給你n 個數,和n 個詢問,每個詢問有l,r,x,問在區間l~r中與x互質的最大位置在哪里?

思路:

以為是個線段樹,想了好久 都沒有確切的好的思路。

其實是容斥定理。

考慮30:

質因子分解 30 = 2*3 *5

那么我們可以求出l到r中 與30 不互質的數有幾個。

很顯然那些數滿足 有2的因子或者有3 的因子或者有5的因子。是一個并集。

那么我們就加上2的個數 加上3的個數 加上5的個數 減去2*3的個數.......

很顯然  這些系數恰好是 莫比烏斯函數。

數值都是10W以內,直接跑一個10W莫比烏斯系數。進行容斥定理即可。

這樣就能快速求出一個區間內與x不互質的個數。

在考慮最大位置。

直接二分了。

m到,R區間 有的話 就更新L到m 否則 更新R到m。

詳細見代碼:

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#define Siz(x) (int)x.size()using namespace std;const int maxn = 1e5 + 7;int mu[maxn];bool vis[maxn];int a[maxn], sum1[maxn];vector<int>fac[maxn],g[maxn];void init(){    mu[1] = 1;    for (int i = 1; i < maxn; ++i) if (mu[i]){        for (int j = i; j < maxn; j+=i)fac[j].push_back(i);        for (int j = i+i; j < maxn; j += i) mu[j]-=mu[i];    }    for (int i = 2; i < maxn; ++i){        if (mu[i])mu[i] = -mu[i];    }}void add(int x,int id){    for (int i = 0; i < Siz(fac[x]); ++i){        int v = fac[x][i];        g[v].push_back(id);    }}int calc(int l,int r,int x){    int ans = 0;    for (int i = 1; i < Siz(fac[x]); ++i){        int v = fac[x][i];        int p1 = lower_bound(g[v].begin(),g[v].end(),l)-g[v].begin();        int p2 = lower_bound(g[v].begin(),g[v].end(),r+1)-g[v].begin();        ans += mu[v] * (p2-p1);    }    return r-l+1 - (ans);}int solve(int l,int r,int x){    if(calc(l,r,x) == 0) return -1;    int L = l,R = r;    int ans;    while(L < R){        int m = L+R>>1;        if (calc(m+1,R,x))L = m+1;        else R = m;    }    return L;}int main(){    init();    int n,q;    while(~scanf("%d %d",&n, &q)){        sum1[0] = 0;        for (int i = 0; i < maxn; ++i)g[i].clear();        for (int i = 1; i <= n; ++i){            scanf("%d",&a[i]);            sum1[i] = sum1[i-1];            if (a[i] == 1){                sum1[i]++;            }            add(a[i],i);        }        while(q--){            int l,r,x;            scanf("%d %d %d",&l, &r, &x);            if (x == 1) PRintf("%d/n",r);            else{                int ans = solve(l,r,x);                printf("%d/n",ans);            }        }    }    return 0;}/**5 41 2 3 4 61 5 21 1 14 5 23 5 3**/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 濮阳市| 穆棱市| 开化县| 北海市| 会宁县| 闸北区| 枣阳市| 辛集市| 随州市| 成安县| 新乡县| 容城县| 抚松县| 邮箱| 读书| 新巴尔虎左旗| 黄龙县| 安阳市| 桐乡市| 屯留县| 大连市| 临泉县| 宁化县| 织金县| 靖西县| 榆社县| 车致| 景德镇市| 琼海市| 晴隆县| 南丰县| 农安县| 巫溪县| 象山县| 咸阳市| 申扎县| 东辽县| 阜康市| 渭源县| 峡江县| 青岛市|