尤拉函式 線段樹 奇數國

2022-03-27 06:32:51 字數 2912 閱讀 5749

問題 b: 奇數國

時間限制: 1 sec 記憶體限制: 256 mb

提交: 82 解決: 44

[提交][狀態][討論版]

題目描述

在一片美麗的大陸上有100000個國家,記為1到100000。這裡經濟發達,有數不盡的賬房,並且每個國家有乙個銀行。某大公司的領袖在這100000個銀行開戶時都存了3大洋,他惜財如命,因此會不時地派小弟gfs清點一些銀行的存款或者讓gfs改變某個銀行的存款。該村子在財產上的求和運算等同於我們的乘法運算,也就是說領袖開戶時的存款總和為3100000。這裡發行的軟妹面額是最小的60個素數(p1=2,p2=3,…,p60=281),任何人的財產都只能由這60個基本面額表示,即設某個人的財產為fortune(正整數),則fortune=p1^k1*p2^k2*……p60^k60。

領袖習慣將一段編號連續的銀行裡的存款拿到乙個賬房去清點,為了避免gfs串通賬房叛變,所以他不會每次都選擇同乙個賬房。gfs跟隨領袖多年已經摸清了門路,知道領袖選擇賬房的方式。如果領袖選擇清點編號在[a,b]內的銀行財產,他會先對[a,b]的財產求和(計為product),然後在編號屬於[1,product]的賬房中選擇乙個去清點存款,檢驗自己計算是否正確同時也檢驗賬房與gfs是否有勾結。gfs發現如果某個賬房的編號number與product相沖,領袖絕對不會選擇這個賬房。怎樣才算與product不相沖呢?若存在整數x,y使得number*x+product*y=1,那麼我們稱number與product不相沖,即該賬房有可能被領袖相中。當領袖又賺大錢了的時候,他會在某個銀行改變存款,這樣一來相同區間的銀行在不同的時候算出來的product可能是不一樣的,而且領袖不會在某個銀行的存款總數超過1000000。

現在gfs預先知道了領袖的清點存款與變動存款的計畫,想請你告訴他,每次清點存款時領袖有多少個賬房可以供他選擇,當然這個值可能非常大,gfs只想知道對19961993取模後的答案。

輸入 第一行乙個整數x表示領袖清點和變動存款的總次數。

接下來x行,每行3個整數ai,bi,ci。ai為0時表示該條記錄是清點計畫,領袖會清點bi到ci的銀行存款,你需要對該條記錄計算出gfs想要的答案。ai為1時表示該條記錄是存款變動,你要把銀行bi的存款改為ci,不需要對該記錄進行計算。

輸出 輸出若干行,每行乙個數,表示那些年的答案。

樣例輸入

6 013

115

013

117

013

023

樣例輸出

18 24

36 6

explanation

初始化每個國家存款都為3;

1到3的product為27,[1,27]與27不相沖的有18個數;

1的存款變為5;

1到3的product為45,[1,45]與45不相沖的有24個數;

1的存款變為7;

1到3的product為63,[1,63]與63不相沖的有36個數;

2到3的product為9,[1,9]與9不相沖的有6個數。

提示 x≤100000,當ai=0時0≤ci−bi≤100000

說白了要求數列某一段乘積的尤拉函式.

根據尤拉定理,φ(n)=n*∏((p-1)/p) (p為n的質因數)

一棵線段樹維護這一段乘積,並維護這一段有哪些質數。而題目中指出只會用到60個質數,那就很方便了,可以狀壓一下,用二進位制記錄下有哪些質數,60剛好不會爆long long.

#include 

#include

#include

#include

#include

#define mod 19961993

#define n 100000

#define ll long long

using namespace std;

intread()

while(x>='0'&&x

<='9')

return sum*f;

}struct tree

t[n*4+100];

intm;

ll s1,s2,ans,xp[65],hh[65],pri[65]=;

ll cheng(ll x,ll m)

return ans;

}void build(int l,int r,int

x) int mid=l+r>>1;

build(l,mid,x

*2);

build(mid+1,r,x

*2+1);

t[x].h=t[x

*2].h*t[x

*2+1].h%mod;

t[x].sum=t[x

*2].sum|t[x

*2+1].sum;

}void c(int l,int k,int

x) int mid=t[x].l+t[x].r>>1;

if(l<=mid)c(l,k,x

*2);

else c(l,k,x

*2+1);

t[x].h=t[x

*2].h*t[x

*2+1].h%mod;

t[x].sum=t[x

*2].sum|t[x

*2+1].sum;

}void q(int l,int r,int x)

int mid=t[x].l+t[x].r>>1;

if(l<=mid)q(l,r,x*2);

if(r>mid)q(l,r,x*2+1);

}int main()

xp[0]=1;for(int i=1;i<=60;i++)xp[i]=xp[i-1]*2ll;

build(1,n,1);

intx,a,b;

while(m--)

else c(a,b,1);

}}

bzoj3813 奇數國 線段樹 尤拉函式

傳送門這題目是真的難讀.閱讀理解題啊.但是理解了以後就發現,題目等價於 給你乙個區間,支援單點修改,以及查詢一段區間的乘積的尤拉函式值,這個答案對19961993取模 這裡是尤拉函式的原因顯然,題目中的那個不相沖實際上就是擴充套件歐幾里得裡面的那個定理,要滿足不相沖 也就是方程有解 product ...

bzoj3813 奇數國 線段樹

題目描述 給出乙個長度為n的序列,每個數都可以由前60個質數的乘積表示,初始每個數都是3。支援兩種操作 1 修改乙個數 2 查詢一段區間內所有數的乘積的尤拉函式值模19961993。輸入第一行乙個整數x表示領袖清點和變動存款的總次數。接下來x行,每行3個整數ai,bi,ci。ai為0時表示該條記錄是...

線段樹,區間更新 尤拉函式

區間更新,學會了一種 新的更新姿勢。hdu 5634 操作1,給定區間,在區間內的 每個單點,按照函式變換 操作2,區間更新,修個整個區間內所有的值 操作3,求和 include include include include include define lson l,m,rt 1 define ...