這題碼農,表示又被出題人虐了。
我們發現ai
以及x
於是我們用線段樹,對於每個區間記錄109個質數被該區間多少個數包含。
由於要區間修改,我們再記錄109個la
zy,表示該區間該質數還要下傳多少次。
那麼,現在我們知道φ(
n)=n
∏mi=
1(1−
1pi)
(pi 表示的
n 質因數,
m表示質因數的種數)。
觀察上面的式子,乙個很顯然的結論是φ(
pn)=
pφ(n
)(p|
n)(這裡
p 是質因數)
那如果p不是n
的質因數呢?那麼φ
(pn)
=p(1
−1p)
φ(n)
=(p−
1)φ(
n)。那麼至於區間乘上乙個數
x ,先給它分解質因數,得出∏m
i=1x
kii=
x 對於乙個質因數xi
,我們已知該區間有ax
i 個數包含它,那麼它們對尤拉積的貢獻為:xa
xii 。
但是,沒有包含的怎麼辦?由上可得,沒有包含的將乘上乙個(x
i−1)
,所以該區間沒有被包含的對尤拉積的貢獻就為:(x
i−1)
r−l+
1−ax
i 。
最後給修改的區間打上la
zy標記即可。
但是,怎樣下傳標記?
我們對於乙個區間有la
zyi 表示第
i 個質數還要下傳多少次。那麼,我們先給這個區間下傳一次,具體下傳請看上述修改部分。然後,由於還要下傳(l
azyi
−1)次,而且因為已經下傳過一次,所以整個區間都有包含了第
i 個質數,剩下的貢獻就為:(p
rr−l
+1i)
lazy
i−1(這裡pr
i 表示第
i 個質數)。
對於查詢,直接找到區間尤拉積即可。
時間複雜度:o(
109nlo
g22n
) 然而,這題看似容易,實際上打對調對需要花費大量時間。
可以打乙個線性篩法求
φ 來方便除錯。
#include
#include
#include
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define n 10010
#define m 601
#define mo 100000007
#define ll long long
using namespace std;
int pr[m],cnt=0,phi[m];
int a[n];
bool bz[m];
struct nodetr[n*4];
int ph[n],s1[n],s2[n];
int ls[120];
intmap[m];
ll pow(ll m,int n)
return b;
}void pre()
else phi[i*pr[j]]=phi[i]*(pr[j]-1);}}
}void get(int v,int
x) }
if(x>1) tr[v].a[map[x]]=1;
}void getlazy(int v,int
x) }
if(x>1) tr[v].lz[map[x]]++,ls[map[x]]++;
}void put(int v,int l,int r)
}void build(int v,int l,int r)
int mid=(l+r)/2;
build(v*2,l,mid);
build(v*2+1,mid+1,r);
fo(i,1,109)
tr[v].a[i]=tr[v*2].a[i]+tr[v*2+1].a[i];
tr[v].s=tr[v*2].s
*tr[v*2+1].s
%mo;
}void change(int v,int l,int r,int
x,int
y,int p)
return;
}put(v,l,r);
int mid=(l+r)/2;
if(y
<=mid) change(v*2,l,mid,x,y,p);
else
if(x>mid) change(v*2+1,mid+1,r,x,y,p);
else
fo(i,1,109)
tr[v].a[i]=tr[v*2].a[i]+tr[v*2+1].a[i];
tr[v].s=tr[v*2].s
*tr[v*2+1].s
%mo;
}ll ans=1;
void find(int v,int l,int r,int
x,int
y) int mid=(l+r)/2;
put(v,l,r);
if(y
<=mid) find(v*2,l,mid,x,y);
else
if(x>mid) find(v*2+1,mid+1,r,x,y);
else
}int main()
else}}
普及 模擬 開關燈泡(jzoj第三題)
題目 description 乙個房間裡有n盞燈泡,一開始都是熄著的,有1到n個時刻,每個時刻i,我們會將i的倍數的燈泡改變狀態 即原本開著的現將它熄滅,原本熄滅的現將它點亮 問最後有多少盞燈泡是亮著的。input 乙個數n output m,表示最後有m盞是亮著的 sample input sam...
JZOJ 7 7C組第三題 頁
給出奇數個數,每次把它中間的數取出來放到最左邊或最右邊,求出最少取多少次可以讓這些數是從小到大的。bfs hash判重。每次左邊右邊操作一次,判斷之前有沒有出現過了,沒有就入隊。include define maxn 300017 using namespace std int n,state 10...
JZOJ 7 9C組第三題 排列的編碼
給出乙個長度為n序列,求出它在n的全排列中是第幾個。這道題要找規律,設ml i ml i 為第i i 位後面有幾個數比第 i role presentation style position relative i i位小,通過一系列操作 詳見某蒟佬 可以得到答案an s an s ml i n i ...