1. 程式人生 > >(hdu4407)Sum(容斥原理)

(hdu4407)Sum(容斥原理)

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3639 Accepted Submission(s): 1047

Problem Description
XXX is puzzled with the question below:

1, 2, 3, …, n (1<=n<=400000) are placed in a line. There are m (1<=m<=1000) operations of two kinds.

Operation 1: among the x-th number to the y-th number (inclusive), get the sum of the numbers which are co-prime with p( 1 <=p <= 400000).
Operation 2: change the x-th number to c( 1 <=c <= 400000).

For each operation, XXX will spend a lot of time to treat it. So he wants to ask you to help him.

Input
There are several test cases.
The first line in the input is an integer indicating the number of test cases.
For each case, the first line begins with two integers — the above mentioned n and m.
Each the following m lines contains an operation.
Operation 1 is in this format: “1 x y p”.
Operation 2 is in this format: “2 x c”.

Output
For each operation 1, output a single integer in one line representing the result.

Sample Input
1
3 3
2 2 3
1 1 3 4
1 2 3 6

Sample Output
7
0

Source
2012 ACM/ICPC Asia Regional Jinhua Online

題意:給定n和m,m個操作,操作有以下兩種型別:
1. 1 x y p 計算[x,y]內與p互質的數的總和
2. 2 x c 將第x個數改為c(最多1000次)
輸出操作1所求的和

分析:求[x,y]內與p互質的數,這裡和 hdu4315(http://blog.csdn.net/feng_zhiyu/article/details/76176070) 類似 對p分解,求出其素因子並儲存
設 p 的素因子是{P1,P2,…,Pk},於是與 p 不互質的數的素因子集合可以表示成 {P1} U {P2} U … U {Pk}。
那麼與 p 不互質的數的集合可以表示成 W = { P1的倍數 } U { P2的倍數 } U … U { Pk的倍數 }。
其中,{ Pk的倍數 } = { Pk*1 } + { Pk*2 } + … + { Pk*Mk } ( Pk*Mk<=n && Pk*(Mk+1)>n )。
從而,ans = sum{ W }。
於是可以通過容斥原理,求得問題的解。
舉個簡單的例子,假如 k=2,則 ans = 【sum{ P1的倍數 } + sum{ P2的倍數 } - sum{ P1*P2的倍數 }】。其中,某個sum{ }可以通過等差公式求得。
第二種操作 直接一一判斷

打算把容斥原理的三種方法都用一遍,但開始我用佇列的時候TLE了,發現有一個地方寫錯了,改了過來變成了WA。。 感覺沒問題。。 dfs也有點問題。。 先放上來。。。

#include<cstdio>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL N=1e6+5;
LL vec[N];
map<LL,LL>mp;
LL n,m,cnt;
void is_sfactor(LL n)///求n的素因子
{
    cnt=0;
    for(LL i=2; i*i<=n; i++)
    {
        if(n%i==0)
        {
            n/=i;
            vec[cnt++]=i;
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1) vec[cnt++]=n;
}
LL gcd(LL a,LL b)
{
    return b==0?a:gcd(b,a%b);
}
LL que[N];
LL solve(LL x,LL p)///求[1,x]內與p互質的數
{
    LL ans=x*(1+x)/2;//先求出總和
    LL len=cnt;
    /*LL k,front=0,T;
    que[front++]=-1;
    for(LL i=0; i<len; i++)
    {
        k=front;
        for(LL j=0; j<k; j++)
            que[front++]=que[j]*vec[i]*(-1);
    }
    for(LL i=1; i<front; i++)
    {
        T=(x/que[i])*(que[i]+(x/que[i])*que[i])/2;
        if(que[i]<0)
            ans+=T;
        else ans-=T;
    }*/
    for(LL i=1; i<(1<<len); i++)///二進位制位實現容斥
    {
        LL num=0;
        LL k=1;
        for(LL j=0; j<len; j++)
            if(i&(1<<j))
            {
                num++;
                k*=vec[j];
            }
        k=(x/k)*(k+(x/k)*k)/2;
        if(num&1) ans-=k;///  奇數的 是不互質的數
        else ans+=k;  //加上重複減去的
    }
    return ans;
}
LL query(LL ans,LL x,LL y,LL p)
{
    map<LL,LL>::iterator it;
    for(it=mp.begin(); it!=mp.end(); it++)
    {
        LL g1=it->first,g2=it->second;
        if(it->first>=x&&it->first<=y) ///必須滿足在查詢的區間內
        {
            if(gcd(g1,p)==1) ans-=g1; ///原來被修改的數
            if(gcd(g2,p)==1) ans+=g2;  ///修改後的數
        }
    }
    return ans;
}
int main()
{
    LL T;
    scanf("%d",&T);
    while(T--)
    {
        mp.clear();
        scanf("%lld%lld",&n,&m);
        while(m--)
        {
            LL type,x,y,p,c;
            scanf("%lld",&type);
            if(type==1)
            {
                scanf("%lld%lld%lld",&x,&y,&p);
                is_sfactor(p);
                LL ans=solve(y,p)-solve(x-1,p);
                //         printf("%LLd\n",ans);
                printf("%lld\n",query(ans,x,y,p));
            }
            else
            {
                scanf("%lld%lld",&x,&c);
                mp[x]=c;
            }
        }
    }
    return 0;
}

相關推薦

【BZOJ1008】越獄排列組合計數,原理

code typedef ostream ima bzoj1008 image sca fin space 題意: 思路: 1 #include<cstdio> 2 #include<cstdlib> 3 #include<ios

ACM-ICPC 2018瀋陽網路賽G題唯一分解定理、原理

A sequence of integer \lbrace a_n \rbrace{an​} can be expressed as: \displaystyle a_n = \left\{ \begin{array}{lr} 0, & n=0\\ 2, &am

BZOJ3589 動態樹樹鏈剖分+原理

std class down ring print color 動態 inf while   顯然容斥後轉化為求樹鏈的交。這個題非常良心的保證了查詢的路徑都是到祖先的,求交就很休閑了。 #include<iostream> #include<cstdi

求1~n與x互質的數的個數6個題、原理

HDU 4135、POJ 2773、HDU 1695、HDU 2841、ZOJ 2836、HDU 1796 HDU 4135 Co-prime 題意: 求[l,r]與x互質的數的

hdu4407Sum原理

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3639 Accepted Submissi

hdu 4407 SUM原理

題意: 有一個元素為 1~n 的數列An,有2種操作(最多1000次): 1. 求某段區間 [a,b] 中與 p 互質的數的和。 2. 將數列中某個位置元素的值改變。 解析:

#19. 計數原理

cnblogs += void lld ring 輸入輸出 計數 define printf 時間限制:1s 內存限制:256MB 【問題描述】 給出m個數a[1],a[2],…,a[m] 求1~n中有多少數不是a[1],a[2],…,a

BZOJ3771 TripleFFT+原理

ble algo pan double == max [] urn cstring   思路比較直觀。設A(x)=Σxai。先把只選一種的統計進去。然後考慮選兩種,這個直接A(x)自己卷起來就好了,要去掉選同一種的情況然後除以2。現在得到了選兩種的每種權值的方案數,再把這個

『ZOJ 3547』The Boss on Mars 原理

ostream idt employee ant mars pri mes because reason 傳送門戳這裏qwq 題目描述 On Mars, there is a huge company called ACM (A huge Company on M

GCD HDU - 1695原理

stdin false print ont 分享 typedef vector swa sed 要求從滿足gcd(x, y) = k的對數,其中x屬於[1, n], y屬於[1, m] gcd(x, y) = k ==>gcd(x/k, y/k) =1 x/k

HDU - 6314 Matrix廣義原理

bsp tar std sdn spa -i const long span http://acm.hdu.edu.cn/showproblem.php?pid=6314 題意 對於n*m的方格,每個格子只能塗兩種顏色,問至少有A列和B行都為黑色的方案數是多少。 分析

Codeforces 451 E. Devu and Flowers組合數學,數論,原理

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

Newcoder 39 E.集合中的質數原理

Description 給出一個集合和一個數 m m m。 集合裡面有

【ZOJ - 2836 】Number Puzzle 原理

題幹: Given a list of integers (A1, A2, ..., An), and a positive integer M, please find the number of positive integers that are not greater than M

HDU-1796 How many integers can you find原理

                            How many integers can you find      

Codeforces483B. Friends and Presents二分+原理

題目連結:傳送門 題目: B. Friends and Presents time limit per test 1 second memory limit per test 256 megabytes input standard input output standard out

BZOJ4767 兩雙手組合數學+原理

  因為保證了兩向量不共線,平面內任何一個向量都被這兩個向量唯一表示。問題變為一張有障礙點的網格圖由左上走到右下的方案數。   到達終點所需步數顯然是平方級別的,沒法直接遞推。注意到障礙點數量很少,那麼考慮容斥,即用總方案數減去經過障礙點的方案數。對每個障礙點計算其作為第一個經過的障礙點的方案數即可。

【HDOJ5514】Frogs原理

題意:n個青蛙在一個有m個節點的圓上跳,m個節點的標號為0-m-1,每隻青蛙每次跳的節點數給出,讓求n只青蛙所跳位置標號之和 n<=1e4,m<=1e9,a[i]<=1e9 思路:由裴蜀定理可知該問題等價於[0,m-1]能被至少一個gcd(m,a[i])整除的數字之和 因為n過大,考慮

hdu4135 Co-prime原理

題意:給定一個左端點L,右端點R,問L-R間有多少個數與N互質,注意1與任何數均互質。 題解:容斥原理,對N分解質因數,然後容斥原理找出這些質因數的倍數的個數,即與N不互質的數, 分別統計1-R中不互質,1-(L-1)中不互質,二者作差即為L-R中不互質,再用區間長度

Number Puzzle原理

Given a list of integers (A1, A2, …, An), and a positive integer M, please find the number of positive integers that are not greate