問題 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 ...