傳送門
以前沒見過的套路題……
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 usingnamespace
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.資訊將你我...