維護乙個長度為n的陣列,m個操作,支援兩種操作:
0 l r表示將第l個到第r個數中的每乙個數ai替換為c^ai;
1 l r求第l個到第r個數的和。
首先要知道擴充套件尤拉定理:如果a
>ph
i(p)
,ca≡
c(am
odph
i(p)
)+ph
i(p)
modp
a>phi(p) ,c^\equiv c^ \mod p
a>ph
i(p)
,ca≡
c(am
odph
i(p)
)+ph
i(p)
modp
在多次執行替換操作後,a[i
]a[i]
a[i]
將會變為ccc
...m
odph
i(1)
+phi
(1
)c^\mod phi(1) + phi(1) }}
ccc...
modp
hi(1
)+ph
i(1)
,然後它的值就不會在改變了。
假設在不斷取phi
phiph
i的情況下,p
pp經過k
kk次變為1,易知k
<=l
og(p
)k<=log(p)
k<=l
og(p
)所以,我們可以用線段樹維護區間和,以及區間最少的替換操作次數。
當它的替換操作次數小於k
kk時,直接暴力修改它的值。
當區間最少的替換操作次數都大於等於k
kk時,這段區間和就不會改變了。
時間複雜度o(m
log(
n)lo
g2(p
))
o(mlog(n)log^2(p))
o(mlog
(n)l
og2(
p))。
注意p hi
phiph
i必須取到1,不能再phi
(2)=
1phi(2)=1
phi(2)
=1時結束。
詳見**:
#include
#include
using namespace std;
#define maxn 50010
intpowmod
(int a,
int b,
int mo,bool &f)
return ret;
}int a[maxn]
,p[maxn]
,c,n,m,k;
intwork
(int x,
int dep)
return ret%p[dep];}
intphi
(int x)
if(x!=
1) ret=ret/x*
(x-1);
return ret;
}int sum[maxn*4]
,tag[maxn*4]
;void
pushup
(int i)
void
build
(int i,
int l,
int r)
int mid=
(l+r)
>>1;
build
(i<<
1,l,mid)
;build
(i<<1|
1,mid+
1,r)
;pushup
(i);
}void
modify
(int i,
int l,
int r,
int l,
int r)
int mid=
(l+r)
>>1;
if(l<=mid)
modify
(i<<
1,l,mid,l,r);if
(r>mid)
modify
(i<<1|
1,mid+
1,r,l,r)
;pushup
(i);
}int
ask(
int i,
int l,
int r,
int l,
int r)
intmain()
}
bzoj4869 Shoi2017 相逢是問候
time limit 40 sec memory limit 512 mb submit 1311 solved 470 submit status discuss informatikverbindetdichundmich.資訊將你我鏈結。b君希望以維護乙個長度為n的陣列,這個陣列的下標為從1到...
Bzoj3562 神器化合物 Shoi 2014
ac通道 分析 若把每乙個原子看作乙個節點,將化學鍵看作一條邊,那麼這個題目要求的 分子的個數 很容易就可以看出是求圖中聯通塊的個數。求聯通塊的個數,可以使用並查集。可如何求出每一步的聯通塊的個數呢?可以知道,當連上一條邊時,若此邊連線的是兩個不同的聯通塊,那麼分子個數就會減一 當刪去一條邊時,若刪...
4869 Shoi2017 相逢是問候
4869 shoi2017 相逢是問候 time limit 40 sec memory limit 512 mb submit 440 solved 124 submit status discuss description informatikverbindetdichundmich.資訊將你我...