BZOJ 4809 相逢是問候

2022-05-13 10:02:01 字數 1806 閱讀 5583

傳送門

以前沒見過的套路題……

1、使用ext尤拉定理降冪的套路:

$a^=a^ mod p$,$x\ge p$

這樣對於$c^}modp$就能遞推/遞迴得套用上述定理計算,每層模數多套一層$\phi$即可

注意每次在快速冪時要判斷當前指數是否大於當前模數才能用ext!

2、能證明乙個數最多求$log$次$\phi$就會變成1

這樣在$log$次內暴力更新,否則不管,就能保證$o(n*log^3)$

3、複雜度中的3個$log$分別是:

更新$log$次,每次更新迭代$log$層,每層要算一次快速冪

明顯只能優化快速冪。由於底不變,模數只有$log$種,想到分數的前後兩部分預處理

分塊預處理出$[1,(1<<16)]$和$[1*(1<<16),(1<<16)*(1<<16)]$的答案以及與模數的大小關係

這樣每次拆出指數的前16位和後16位$o(1)$計算答案和大小關係就能做到$o(n*log^2)$

4、聽說原題資料鍋了……

雖然$\phi(2)$和$\phi(1)$都為1,但要更新到$\phi(1)$!

否則在最頂層指數為0時最終會迭代出$cmod2$而非$cmod1$,不一定為0!

#include using

namespace

std;

#define x first

#define y second

#define pb push_backtypedef

double

db;typedef

long

long

ll;typedef pair

p;const

int maxn=1e5+10

;ll pre[

35][1

<<16][2

];bool f[35][1

<<16][2

];int n,m,p,c,dat[maxn],phi[35

],cnt;

int getphi(int

x)

if(x!=1) ret=ret/x*(x-1

);

return

ret;

}ll quick_pow(ll a,ll b,ll mod,

bool &f)

return

ret;

}int qp(int x,int num,bool &flag)

int cal(int x,int

st)

return ret%p;

}void

pre()

}}namespace

segmenttree

void build(int k,int l,int

r)

build(lc);build(rc);pushup(k);

}void modify(int a,int b,int k,int l,int

r)

if(a<=mid) modify(a,b,lc);

if(b>mid) modify(a,b,rc);

pushup(k);

}int query(int a,int b,int k,int l,int

r)

}using

namespace

segmenttree;

intmain()

return0;

}

SHOI 2017 相逢是問候

loj 2142 相逢是問候 首先 這道題目很輕易地就能想到用線段樹求和 但是題目的難點在於 ca imodp caimod pmodp 解決這個問題的公式是 ab abmod p b ai p modp 根據這個公式逆推一下 ca imodp caimod p ai p p modp 以下簡寫 b...

Shoi2017 相逢是問候

傳送門 這種 暴力線段樹 可以考慮一下是不是有什麼特殊性質。對於這道題什麼要知道 可能這裡寫得比較清楚 摘自 感覺就是乙個迭代的過程。而乙個數在操作k次之後就可以不用再操作了。然後使用尤拉定理的時候要特判一下 x phi時,最後要加乙個phi 小於則不加。預處理出所有的phi,記得最後乙個phi為1...

4869 Shoi2017 相逢是問候

4869 shoi2017 相逢是問候 time limit 40 sec memory limit 512 mb submit 440 solved 124 submit status discuss description informatikverbindetdichundmich.資訊將你我...