模板库
「Pre」
临近 CSP-S2 2021 的时候,我决定把板子都打一遍,顺便就把这些板子整理成一个模板库罢。
然而 CSP-S2 2021 都爆了我还没整完(
现在备战 NOIP2022 了(
本模板库最新的内容为 2022.2.20 更新,最老内容为 2022.1.23 更新,最近的码风翻新日期为 2022.1.23.
以下代码若无特殊情况皆可使用的缺省源:
UPD 2022.1.23
#include <bits/stdc++.h>
#define Heriko return
#define Deltana 0
#define Romanno 1
#define S signed
#define LL long long
#define DB double
#define R register
#define I inline
#define CI const int
#define CL const long long
#define mkp(a,b) make_pair(a,b)
#define mst(a,b) memset(a,b,sizeof(a))
#define ON std::ios::sync_with_stdio(false);cin.tie(0)
#define Files() freopen("RNMTQ.in","r",stdin);freopen("RNMTQ.out","w",stdout)
using namespace std;
template<typename J>
I void fr(J &x) {
short f(1);
x=0;
char c(getchar());
while(c<'0' or c>'9') {
if(c=='-')
f=-1;
c=getchar();
}
while(c>='0' and c<='9') {
x=(x<<3)+(x<<1)+(c^=48);
c=getchar();
}
x*=f;
}
template<typename J>
I void fw(J x,bool k) {
if(x<0)
x=-x,putchar('-');
static short stak[35];
short top(0);
do {
stak[top++]=x%10;
x/=10;
}
while(x);
while(top)
putchar(stak[--top]+'0');
k?puts(""):putchar(' ');
}
「快速排序」
UPD 2022.1.23
CI MXX(1e5+1);
int a[MXX];
void Mysort(int l,int r) {
int i(l),j(r),mid(a[(l+r)>>1]);
do {
while(a[i]<mid)
++i;
while(a[j]>mid)
--j;
if(i<=j)
swap(a[i],a[j]),++i,--j;
}
while(i<=j);
if(l<j)
Mysort(l,j);
if(i<r)
Mysort(i,r);
}
int n;
S main() {
fr(n);
for(int i(1);i<=n;++i)
fr(a[i]);
Mysort(1,n);
for(int i(1);i<=n;++i)
fw(a[i],0);
Heriko Deltana;
}
「并查集」
仅使用了路径压缩。
UPD 2022.1.23
CI MXX(2e5+1),NXX(10001);
int fa[NXX],n,m;
int Find(int x) {
if(fa[x]!=x)
fa[x]=Find(fa[x]);
Heriko fa[x];
}
I void Uni(int x,int y) {
int fx(Find(x)),fy(Find(y));
if(fx!=fy)
fa[fx]=fy;
}
S main() {
fr(n),fr(m);
for(int i(1);i<=n;++i)
fa[i]=i;
for(int i(1);i<=m;++i) {
int x,y,z;
fr(z),fr(x),fr(y);
if(z==1)
Uni(x,y);
else {
if(Find(x)==Find(y))
puts("Y");
else
puts("N");
}
}
Heriko Deltana;
}
「线性筛」
这里是按照洛谷模板来写的,不过平时用不着询问部分,主要是
Es
函数。UPD 2022.1.23
CI MXX(1e8+1);
int n,prime[MXX],cnt,q;
bool nopr[MXX];
I void Es() {
nopr[1]=1;
for(int i(2);i<=n;++i) {
if(!nopr[i])
prime[++cnt]=i;
for(int j(1);j<=cnt and prime[j]*i<=n;++j) {
nopr[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
S main() {
fr(n),fr(q);
Es();
while(q--) {
int x;
fr(x);
fw(prime[x],1);
}
Heriko Deltana;
}
「堆」
一般来说,都直接用
priority_queue
.UPD 2022.1.23
priority_queue< int,vector<int>,greater<int> > q;
int n;
S main() {
fr(n);
while(n--) {
int opt,x;
fr(opt);
if(opt==1)
fr(x),q.push(x);
else if(opt==2)
fw(q.top(),1);
else
q.pop();
}
Heriko Deltana;
}
「单调栈」
UPD 2022.1.23
CI MXX(3e6+1);
int n,a[MXX],f[MXX],stak[MXX],top;
S main() {
fr(n);
for(int i(1);i<=n;++i)
fr(a[i]);
for(int i(n);i>=1;--i) {
while(top and a[stak[top]]<=a[i])
--top;
f[i]=top?stak[top]:0;
stak[++top]=i;
}
for(int i(1);i<=n;++i)
fw(f[i],0);
Heriko Deltana;
}
「快速幂」
2021.12.25 更新了那行
x%=p
,调了三天 ODT 居然是这里爆了……我从来没写过这,于是加上。UPD 2022.1.23
I LL FstPow(LL x,LL y,LL p) {
LL res(1);
x%=p;
while(y) {
if(y&1)
(res*=x)%=p;
(x*=x)%=p;
y>>=1;
}
Heriko res;
}
「单调队列」
第一个循环是求区间最小值,后者则为最大值。
UPD 2022.1.23
CI MXX(1e6+1);
int n,k,a[MXX],qmin[MXX],qmax[MXX],hd(1),tl;
S main() {
fr(n),fr(k);
for(int i(1);i<=n;++i)
fr(a[i]);
for(int i(1);i<=n;++i) {
while(hd<=tl and a[qmin[tl]]>=a[i])
--tl;
qmin[++tl]=i;
while(qmin[hd]<=i-k)
++hd;
if(i>=k)
fw(a[qmin[hd]],0);
}
puts("");
hd=1,tl=0;
for(int i(1);i<=n;++i) {
while(hd<=tl and a[qmax[tl]]<=a[i])
--tl;
qmax[++tl]=i;
while(qmax[hd]<=i-k)
++hd;
if(i>=k)
fw(a[qmax[hd]],0);
}
Heriko Deltana;
}
「最小生成树」
UPD 2022.1.23
「Prim」
因为没写挂了(?)暂时咕了
「Kruskal」
CI MXX(2e5+5),NXX(5001);
struct Node {
int x,y,z;
I bool operator < (const Node &co) const {
Heriko z<co.z;
}
}
r[MXX<<1];
int fa[NXX],n,m,ans,k;
int Find(int x) {
if(fa[x]!=x)
fa[x]=Find(fa[x]);
Heriko fa[x];
}
I void Uni(int x,int y,int z) {
int fx(Find(x)),fy(Find(y));
if(fx!=fy) {
fa[fx]=fy;
++k;
ans+=z;
}
}
S main() {
fr(n),fr(m);
for(int i(1);i<=n;++i)
fa[i]=i;
for(int i(1);i<=m;++i)
fr(r[i].x),fr(r[i].y),fr(r[i].z);
std::sort(r+1,r+1+m);
for(int i(1);i<=m;++i) {
Uni(r[i].x,r[i].y,r[i].z);
if(k==n-1)
break;
}
if(k==n-1)
fw(ans,1);
else
puts("orz");
Heriko Deltana;
}
「字符串哈希」
「单哈希+自然溢出」
UPD 2022.1.23
#define LL unsigned long long
const LL b(211),prime(19260817);
LL h[10015];
char s[10015];
int n,ans=1;
I LL hso(char x[]) {
int lx=strlen(x);
LL t=0;
for(int i=0;i<lx;i++)
t=(t*b+(LL)x[i])+prime;
Heriko t;
}
S main() {
fr(n);
for(int i=1;i<=n;i++) {
scanf("%s",s);
h[i]=hso(s);
}
sort(h+1,h+1+n);
for(int i=1;i<n;i++)
if(h[i]!=h[i+1])
ans++;
fw(ans,1);
Heriko Deltana;
}
「双哈希」
UPD 2022.1.23
CI MXX(1501),NXX(10005),MOD1(19260817),MOD2(998244353);
int n;
char s[MXX];
namespace Hash {
#define ULL unsigned long long
struct Node {
ULL h1,h2;
I bool operator < (const Node &co) const {
Heriko (h1==co.h1)?(h2<co.h2):(h1<co.h1);
}
I bool operator != (const Node &co) const {
Heriko !((h1==co.h1)&(h2==co.h2));
}
}
a[NXX];
I void GetHash1(int pos,char s[]) {
int len(strlen(s));
ULL tmp(0);
for(int i(0);i<len;++i)
tmp=(tmp*255+s[i])%MOD1;
a[pos].h1=tmp;
}
I void GetHash2(int pos,char s[]) {
int len(strlen(s));
ULL tmp(0);
for(int i(0);i<len;++i)
tmp=(tmp*255+s[i])%MOD2;
a[pos].h2=tmp;
}
I void GetHash(int pos,char s[]) {
GetHash1(pos,s);
GetHash2(pos,s);
}
I void Solve() {
sort(a+1,a+1+n);
int cnt(0);
for(int i(1);i<=n;++i)
if(a[i]!=a[i-1] or i==1)
a[++cnt]=a[i];
fw(cnt,1);
exit(0);
}
}
S main() {
fr(n);
for(int i(1);i<=n;++i) {
scanf("%s",s+1);
Hash::GetHash(i,s+1);
}
Hash::Solve();
Heriko Deltana;
}
「单端最短路」
「Dijkstra」
UPD 2022.1.23
CI MXX(5e5+1),NXX(1e5+1);
struct node {
int nex,to,val;
}
r[MXX];
int cnt,head[NXX];
I void Add(int x,int y,int z) {
r[++cnt]=(node){head[x],y,z};
head[x]=cnt;
}
struct co {
int dis,id;
I bool operator < (const co &x) const {
Heriko x.dis<dis;
}
};
priority_queue<co> q;
int dis[NXX],n,m,s;
bool vis[MXX];
I void Dijkstra() {
dis[s]=0;
q.push((co){0,s});
while(q.size()) {
int x(q.top().id);
q.pop();
if(vis[x])
continue;
vis[x]=1;
for(int i(head[x]);i;i=r[i].nex) {
int y(r[i].to);
if(dis[y]>dis[x]+r[i].val) {
dis[y]=dis[x]+r[i].val;
if(!vis[y])
q.push((co){dis[y],y});
}
}
}
}
S main()
{
fr(n),fr(m),fr(s);
mst(dis,0x7f);
dis[0]=0;
for(int i(1);i<=m;++i) {
int x,y,z;
fr(x),fr(y),fr(z);
Add(x,y,z);
}
Dijkstra();
for(int i(1);i<=n;++i)
fw(dis[i],0);
Heriko Deltana;
}
「树状数组」
「单点修改区间询问」
UPD 2022.1.23
CI MXX(5e5+1);
#define lowbit(x) (x&(-x))
LL n,t[MXX],a[MXX],m;
I void Modify(int x,int v) {
while(x<=n)
t[x]+=v,x+=lowbit(x);
}
I LL Query(int x) {
int res(0);
while(x)
res+=t[x],x-=lowbit(x);
Heriko res;
}
S main() {
fr(n),fr(m);
for(int i(1);i<=n;++i)
fr(a[i]);
for(int i(1);i<=n;++i)
Modify(i,a[i]);
while(m--) {
int opt,l,r;
fr(opt),fr(l),fr(r);
if(opt==1)
Modify(l,r);
else
fw(Query(r)-Query(l-1),1);
}
Heriko Deltana;
}
「区间修改单点询问」
UPD 2022.1.23
#define lowbit(x) ((x)&(-x))
CI MXX(5e5+1);
int n,m,t[MXX],a[MXX];
I void Add(int x,int val) {
while(x<=n)
t[x]+=val,x+=lowbit(x);
}
I int Query(int x) {
int res(0);
while(x)
res+=t[x],x-=lowbit(x);
Heriko res;
}
S main() {
fr(n),fr(m);
for(int i(1);i<=n;++i)
fr(a[i]);
for(int i(1);i<=n;++i)
Add(i,a[i]-a[i-1]);
while(m--) {
int opt,x,y,z;
fr(opt);
if(opt==1) {
fr(x),fr(y),fr(z);
Add(x,z);
Add(y+1,-z);
}
else {
fr(x);
fw(Query(x),1);
}
}
Heriko Deltana;
}
「乘法逆元」
UPD 2022.1.23
CI MXX(3e6+1);
LL inv[MXX],n,m;
S main() {
fr(n),fr(m);
inv[1]=1;
for(int i(2);i<=n;++i)
inv[i]=m-(m/i)*inv[m%i]%m;
for(int i(1);i<=n;++i)
fw(inv[i],1);
Heriko Deltana;
}
「高精度」
UPD 2022.1.23
CI MXX(105);
struct Pic {
int num[MXX],sz;
Pic() {
mst(num,0);
sz=1;
}
I void Clear() {
mst(num,0);
sz=1;
}
/*---- int * Pic ----*/
I Pic operator * (const int &co) const {
Pic res;
res.sz=sz;
for(int i(1);i<=sz;++i)
res.num[i]=num[i]*co;
for(int i(1);i<=sz;++i)
res.num[i+1]+=(res.num[i]/10),res.num[i]%=10;
while(res.num[res.sz+1]) {
++res.sz;
res.num[res.sz+1]+=(res.num[res.sz]/10);
res.num[res.sz]%=10;
}
Heriko res;
}
/*---- Pic * Pic ----*/
I Pic operator * (const Pic &co) const {
Pic res;
res.sz=co.sz+sz;
for(int i(1);i<=sz;++i)
for(int j(1);j<=co.sz;++j) {
res.num[i+j-1]+=(num[i]*co.num[j]);
res.num[i+j]+=(res.num[i+j-1]/10);res.num[i+j-1]%=10;
}
while(!res.num[res.sz] and res.sz>1)
--res.sz;
Heriko res;
}
/*---- Pic + Pic ----*/
I Pic operator + (const Pic &co) const {
Pic res;
res.sz=sz+2;
for(int i(1);i<=sz;++i) {
res.num[i]+=num[i]+co.num[i];
if(res.num[i]>10)
++res.num[i+1],res.num[i]%=10;
}
while(!res.num[res.sz] and res.sz>1)
--res.sz;
Heriko res;
}
/*---- Pic - Pic ----*/
/*Need to ensure *this > co*/
I Pic operator - (const Pic &co) const {
Pic res;
res.sz=sz;
for(int i(1);i<=sz;++i) {
res.num[i]+=num[i]-co.num[i];
if(res.num[i]<0)
--res.num[i+1],res.num[i]+=10;
}
while(!res.num[res.sz] and res.sz>1)
--res.sz;
Heriko res;
}
/*---- Pic>>1 ----*/
I void RightShift() {
for(int i(sz);i;--i) {
if(num[i]&1)
num[i-1]+=10;
num[i]>>=1;
}
while(!num[sz] and sz>1)
--sz;
}
/*---- Pic < Pic ----*/
I bool operator < (const Pic &co) const {
if(sz!=co.sz)
Heriko sz<co.sz;
for(int i(sz);i;--i)
if(num[i]!=co.num[i])
Heriko num[i]<co.num[i];
Heriko Deltana;
}
/*---- Pic > Pic ----*/
I bool operator > (const Pic &co) const {
if(sz!=co.sz)
Heriko sz>co.sz;
for(int i(sz);i;--i)
if(num[i]!=co.num[i])
Heriko num[i]>co.num[i];
Heriko Deltana;
}
/*---- Pic <= Pic ----*/
I bool operator <= (const Pic &co) const {
Heriko !((*this)>co);
}
/*---- Pic >= Pic ----*/
I bool operator >= (const Pic &co) const {
Heriko !((*this)<co);
}
/*---- Pic == Pic ----*/
I bool operator == (const Pic &co) const {
Heriko (!((*this)>co))&(!((*this)<co));
}
/*---- Pic Input (char[] -> Pic) ----*/
I void Into(char s[]) {
sz=strlen(s+1);
for(int i(1);i<=sz;++i)
num[i]=s[sz-i+1]-'0';
}
/*---- Pic == 0 ? ----*/
I bool Zero() {
Heriko (sz==1)&(num[1]==0);
}
/*---- Pic Output ----*/
I void fw() {
for(int i(sz);i;--i)
putchar(num[i]+'0'); putchar(' ');
}
}
n,m;
「线段树」
UPD 2022.1.23
这里只放了个区间加和区间改,其它东西改一改就有了。
template<typename J>
I J Hmax(const J &x,const J &y) {
Heriko x>y?x:y;
}
const LL MXX(1e6+1),INF(1e12);
int n,q;
struct Node {
int l,r;LL mx,tg1,tg2;
}
t[MXX<<2];
I void Pushup(int x) {
t[x].mx=Hmax(t[lc(x)].mx,t[rc(x)].mx);
}
I void Pushdown(int x) {
if(t[x].tg2!=INF) {
t[lc(x)].tg1=0;
t[lc(x)].tg2=t[x].tg2;
t[lc(x)].mx=t[x].tg2;
t[rc(x)].tg1=0;
t[rc(x)].tg2=t[x].tg2;
t[rc(x)].mx=t[x].tg2;
t[x].tg2=INF;
}
if(t[x].tg1) {
t[lc(x)].tg1+=t[x].tg1;
t[lc(x)].mx+=t[x].tg1;
t[rc(x)].tg1+=t[x].tg1;
t[rc(x)].mx+=t[x].tg1;
t[x].tg1=0;
}
}
void Build(int x,int l,int r) {
t[x].l=l,t[x].r=r;
t[x].mx=t[x].tg1=0;
t[x].tg2=INF;
if(l==r) {
fr(t[x].mx);
Heriko;
}
int mid((l+r)>>1);
Build(lc(x),l,mid);
Build(rc(x),mid+1,r);
Pushup(x);
}
void ModifyAdd(int x,int lx,int rx,LL v) {
if(lx<=t[x].l and t[x].r<=rx) {
t[x].tg1+=v;t[x].mx+=v;
Heriko;
}
Pushdown(x);
int mid((t[x].l+t[x].r)>>1);
if(lx<=mid)
ModifyAdd(lc(x),lx,rx,v);
if(rx>mid)
ModifyAdd(rc(x),lx,rx,v);
Pushup(x);
}
void ModifyChange(int x,int lx,int rx,LL v) {
if(lx<=t[x].l and t[x].r<=rx) {
t[x].tg1=0;t[x].tg2=v;t[x].mx=v;
Heriko;
}
Pushdown(x);
int mid((t[x].l+t[x].r)>>1);
if(lx<=mid)
ModifyChange(lc(x),lx,rx,v);
if(rx>mid)
ModifyChange(rc(x),lx,rx,v);
Pushup(x);
}
LL Query(int x,int lx,int rx) {
if(lx<=t[x].l and t[x].r<=rx)
Heriko t[x].mx;
LL res(-INF);
int mid((t[x].l+t[x].r)>>1);
Pushdown(x);
if(lx<=mid)
res=Hmax(Query(lc(x),lx,rx),res);
if(rx>mid)
res=Hmax(Query(rc(x),lx,rx),res);
Heriko res;
}
S main() {
fr(n),fr(q);
Build(1,1,n);
while(q--) {
int opt,l,r;LL x;
fr(opt),fr(l),fr(r);
if(opt==1)
fr(x),ModifyChange(1,l,r,x);
else if(opt==2)
fr(x),ModifyAdd(1,l,r,x);
else
fw(Query(1,l,r),1);
}
Heriko Deltana;
}
「主席树」
UPD 2022.2.20
CI MXX(1e5+1);
int n,q,lc[MXX<<5],rc[MXX<<5],sum[MXX<<5],t[MXX],a[MXX],b[MXX],id;
int Build(int l,int r) {
int x(++id),mid((l+r)>>1);
if(l<r) {
lc[x]=Build(l,mid);
rc[x]=Build(mid+1,r);
}
Heriko x;
}
int Insert(int pre,int l,int r,int v) {
int x(++id),mid((l+r)>>1);
lc[x]=lc[pre],rc[x]=rc[pre],sum[x]=sum[pre]+1;
if(l<r) {
if(v<=mid)
lc[x]=Insert(lc[pre],l,mid,v);
else
rc[x]=Insert(rc[pre],mid+1,r,v);
}
Heriko x;
}
int Query(int x,int y,int l,int r,int v) {
if(l>=r)
Heriko l;
int nw(sum[lc[y]]-sum[lc[x]]),mid((l+r)>>1);
if(nw>=v)
Heriko Query(lc[x],lc[y],l,mid,v);
else
Heriko Query(rc[x],rc[y],mid+1,r,v-nw);
}
S main() {
fr(n),fr(q);
for(int i(1);i<=n;++i)
fr(a[i]),b[i]=a[i];
sort(b+1,b+1+n);
int nl(unique(b+1,b+1+n)-b-1);
for(int i(1);i<=n;++i)
a[i]=lower_bound(b+1,b+1+nl,a[i])-b;
t[0]=Build(1,nl);
for(int i(1);i<=n;++i)
t[i]=Insert(t[i-1],1,nl,a[i]);
while(q--) {
int l,r,k;
fr(l),fr(r),fr(k);
fw(b[Query(t[l-1],t[r],1,nl,r-l+1-k+1)],1);//求区间第 K 大
fw(b[Query(t[l-1],t[r],1,nl,k)],1);//求区间第 K 小
}
Heriko Deltana;
}
「ST表」
UPD 2022.1.23
template<typename J>
I J Hmax(const J &x,const J &y) {
Heriko x>y?x:y;
}
CI MXX(1e5+1);
LL a[MXX][22];
int n,m;
I LL Query(int l,int r) {
int tmp(std::log2(r-l+1));
Heriko Hmax(a[l][tmp],a[r-(1<<tmp)+1][tmp]);
}
S main() {
fr(n),fr(m);
for(int i(1);i<=n;++i)
fr(a[i][0]);
for(int lg(1);lg<=21;++lg)
for(int i(1);i+(1<<lg)-1<=n;++i)
a[i][lg]=Hmax(a[i][lg-1],a[i+(1<<(lg-1))][lg-1]);
for(int i(1);i<=m;++i) {
int l,r;
fr(l),fr(r);
fw(Query(l,r),1);
}
Heriko Deltana;
}
「三分法」
UPD 2022.1.23
template<typename J>
I J Habs(const J &x) {
Heriko x<0?-x:x;
}
const double EPS(1e-7);
CI MXX(15);
int n;
double a[MXX],l,r;
double Solve(double x) {
double res(0);
for(int i(n);i>=0;--i)
res*=x,res+=a[i];
Heriko res;
}
S main() {
fr(n);
scanf("%lf%lf",&l,&r);
for(int i(n);i>=0;--i)
scanf("%lf",&a[i]);
while(Habs(r-l)>=EPS) {
double mid((l+r)/2);
if(Solve(mid+EPS)>Solve(mid-EPS))
l=mid;
else
r=mid;
}
printf("%.5lf\n",r);
Heriko Deltana;
}
「KMP」
UPD 2022.1.23
CI MXX(1e6+1);
int lena,lenb,nex[MXX],kmp[MXX];
char a[MXX],b[MXX];
S main() {
scanf("%s%s",a+1,b+1);
lena=strlen(a+1),lenb=strlen(b+1);
for(int i(2),j(0);i<=lenb;++i) {
while(j>0 and b[i]!=b[j+1])
j=nex[j];
if(b[i]==b[j+1])
++j;
nex[i]=j;
}
for(int i(1),j(0);i<=lena;++i) {
while(j>0 and a[i]!=b[j+1])
j=nex[j];
if(a[i]==b[j+1])
++j;
kmp[i]=j;
}
for(int i(1);i<=lena;++i)
if(kmp[i]==lenb)
fw(i-lenb+1,1);
for(int i(1);i<=lenb;++i)
fw(nex[i],0);
Heriko Deltana;
}
「LCA」
「倍增」
UPD 2022.1.23
CI MXX(5e5+1);
int n,m,rt;
struct Node {
int nex,to;
}
r[MXX<<1];
int cnt,head[MXX];
I void Add(int x,int y) {
r[++cnt]=(Node){head[x],y};head[x]=cnt;
r[++cnt]=(Node){head[y],x};head[y]=cnt;
}
int dep[MXX],f[MXX][35],lg[MXX];
I void PreLog() {
for(int i(1);i<=n;++i)
lg[i]=lg[i-1]+((1<<lg[i-1])==i);
}
void DFS(int x,int fa) {
f[x][0]=fa;
dep[x]=dep[fa]+1;
for(int i(1);i<=lg[dep[x]];++i)
f[x][i]=f[f[x][i-1]][i-1];
for(int i(head[x]);i;i=r[i].nex)
if(r[i].to!=fa)
DFS(r[i].to,x);
}
I int LCA(int x,int y) {
if(dep[x]<dep[y])
swap(x,y);
while(dep[x]>dep[y])
x=f[x][lg[dep[x]-dep[y]]-1];
if(x==y)
Heriko x;
for(int i(lg[dep[x]]-1);i>=0;--i)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
Heriko f[x][0];
}
S main() {
fr(n),fr(m),fr(rt);
for(int i(1);i<n;++i) {
int x,y;
fr(x),fr(y);
Add(x,y);
}
PreLog();
DFS(rt,0);
for(int i(1);i<=m;++i) {
int x,y;
fr(x),fr(y);
fw(LCA(x,y),1);
}
Heriko Deltana;
}
「树剖」
UPD 2022.1.23
CI MXX(500001);
struct Node {
int nex,to;
}
r[MXX<<1];
int rcnt,head[MXX];
I void Add(int x,int y) {
r[++rcnt]=(Node){head[x],y},head[x]=rcnt;
r[++rcnt]=(Node){head[y],x},head[y]=rcnt;
}
int sz[MXX],son[MXX],top[MXX],fa[MXX],dep[MXX];
void DFS1(int x,int fath) {
sz[x]=1,fa[x]=fath,dep[x]=dep[fath]+1;
for(int i(head[x]);i;i=r[i].nex) {
int y(r[i].to);
if(y==fath)
continue;
DFS1(y,x);
sz[x]+=sz[y];
if(!son[x] or sz[son[x]]<sz[y])
son[x]=y;
}
}
void DFS2(int x,int nw) {
top[x]=nw;
if(son[x])
DFS2(son[x],nw);
for(int i(head[x]);i;i=r[i].nex) {
int y(r[i].to);
if(y==fa[x] or y==son[x])
continue;
DFS2(y,y);
}
}
int n,m,s;
S main() {
// Files();
fr(n),fr(m),fr(s);
for(int i(1);i<n;++i) {
int x,y;
fr(x),fr(y);
Add(x,y);
}
DFS1(s,0);
DFS2(s,s);
for(int i(1);i<=m;++i) {
int x,y;
fr(x),fr(y);
while(top[x]!=top[y]) {
if(dep[top[x]]>=dep[top[y]])
x=fa[top[x]];
else
y=fa[top[y]];
}
fw((dep[x]<dep[y])?x:y,1);
}
Heriko Deltana;
}
「矩阵加速」
UPD 2022.1.23
CI MOD(1e9+7);
int n,T;
struct Matrix {
LL a[5][5];
Matrix() {
mst(a,0);
}
I void BuildB() {
mst(a,0);
a[1][1]=a[1][3]=a[2][1]=a[3][2]=1;
}
I void BuildA() {
mst(a,0);
a[1][1]=a[2][1]=a[3][1]=1;
}
I Matrix operator * (const Matrix &co) const {
Matrix res;
for(int k(1);k<=3;++k)
for(int i(1);i<=3;++i)
for(int j(1);j<=3;++j)
(res.a[i][j]+=(a[i][k]*co.a[k][j])%MOD)%=MOD;
Heriko res;
}
}
A,B;
I void MatrixFstPow(int x) {
while(x) {
if(x&1)
A=A*B;
B=B*B;
x>>=1;
}
}
S main() {
fr(T);
while(T--) {
fr(n);
if(n<=3)
puts("1");
else {
A.BuildA(),B.BuildB();
MatrixFstPow(n-1);
fw((A.a[1][1]+MOD)%MOD,1);
}
}
Heriko Deltana;
}
「SPFA判负环」
UPD 2022.1.23
CI MXX(3001),INF(0x3f3f3f3f);
int n,m,T;
struct Node {
int nex,to,val;
}
r[MXX<<1];
int cnt,head[MXX];
I void Add(int x,int y,int z) {
r[++cnt]=(Node){head[x],y,z};
head[x]=cnt;
}
int co[MXX],dis[MXX];
bitset<MXX> vis;
I bool SPFA(int s) {
queue<int> q;
q.push(s);
dis[s]=0,vis[s]=1,++co[s];
while(q.size()) {
int x(q.front());
q.pop();
vis[x]=0;
for(int i(head[x]);i;i=r[i].nex) {
int y(r[i].to);
if(dis[y]>dis[x]+r[i].val) {
dis[y]=dis[x]+r[i].val;
if(!vis[y]) {
vis[y]=1;
q.push(y);
++co[y];
if(co[y]>n)
Heriko Deltana;
}
}
}
}
Heriko Romanno;
}
S main() {
Files();
fr(T);
while(T--) {
fr(n),fr(m);
cnt=0,vis=0;
mst(dis,0x3f),mst(co,0),mst(head,0);
for(int i(1);i<=m;++i) {
int x,y,z;
fr(x),fr(y),fr(z);
if(z>=0)
Add(x,y,z),Add(y,x,z);
else
Add(x,y,z);
}
if(!SPFA(1))
puts("YES");
else
puts("NO");
}
Heriko Deltana;
}
「矩阵快速幂」
UPD 2022.1.23
CI NXX(101),MXX(21),MOD(1e9+7);
struct Matrix {
int n,m,a[MXX][MXX];
Matrix() {
n=m=0,mst(a,0);
}
I void Build() {
for(int i(1);i<=m;++i)
a[i][i]=1;
}
I Matrix operator * (const Matrix &co) const {
Matrix res;
res.n=n,res.m=co.m;
for(int i(1);i<=n;++i)
for(int k(1);k<=m;++k)
for(int j(1);j<=co.m;++j)
(res.a[i][j]+=(1ll*a[i][k]*co.a[k][j])%MOD)%=MOD;
Heriko res;
}
}
ans;
int n,m;
I Matrix MFP(Matrix x,int y) {
Matrix res;
res.n=res.m=m;
res.Build();
while(y) {
if(y&1)
res=res*x;
x=x*x;
y>>=1;
}
Heriko res;
}
「AC自动机」
UPD 2022.1.23
CI MXX(1e6+5);
struct ACAM {
int c[MXX][26],val[MXX],fail[MXX],cnt;
queue<int> q;
I void Insert(char s[]) {
int len(strlen(s)),nw(0);
for(int i(0);i<len;++i) {
int v(s[i]-'a');
if(!c[nw][v])
c[nw][v]=++cnt;
nw=c[nw][v];
}
++val[nw];
}
I void Build() {
for(int i(0);i<26;++i)
if(c[0][i])
fail[c[0][i]]=0,q.push(c[0][i]);
while(q.size()) {
int x(q.front());
q.pop();
for(int i(0);i<26;++i)
if(c[x][i])
fail[c[x][i]]=c[fail[x]][i],q.push(c[x][i]);
else
c[x][i]=c[fail[x]][i];
}
}
I int Query(char s[]) {
int len(strlen(s)),nw(0),res(0);
for(int i(0);i<len;++i) {
nw=c[nw][s[i]-'a'];
for(int j(nw);j and ~val[j];j=fail[j])
res+=val[j],val[j]=-1;
}
Heriko res;
}
}
AC;
int n;
char s[MXX];
S main() {
Files();
fr(n);
for(int i(1);i<=n;++i)
scanf("%s",s),AC.Insert(s);
AC.Build();
scanf("%s",s);
fw(AC.Query(s),1);
Heriko Deltana;
}
「差分约束」
UPD 2022.1.23
CI MXX(5e3+5),INF(0x3f3f3f3f);
int n,m,T;
struct Node {
int nex,to,val;
}
r[MXX<<1];
int cnt,head[MXX];
I void Add(int x,int y,int z) {
r[++cnt]=(Node){head[x],y,z};
head[x]=cnt;
}
int co[MXX],dis[MXX];
bitset<MXX> vis;
I bool SPFA(int s) {
queue<int> q;
q.push(s);
mst(dis,0x3f);
dis[s]=0,vis[s]=1,++co[s];
while(q.size()) {
int x(q.front());
q.pop();
vis[x]=0;
for(int i(head[x]);i;i=r[i].nex) {
int y(r[i].to);
if(dis[y]>dis[x]+r[i].val) {
dis[y]=dis[x]+r[i].val;
if(!vis[y]) {
vis[y]=1;
q.push(y);
++co[y];
if(co[y]>=n+1)
Heriko Deltana;
}
}
}
}
Heriko Romanno;
}
S main() {
Files();
fr(n),fr(m);
for(int i(1);i<=n;++i)
Add(0,i,0);
for(int i(1);i<=m;++i) {
int x,y,z;
fr(x),fr(y),fr(z);
Add(y,x,z);
}
if(!SPFA(0))
puts("NO");
else
for(int i(1);i<=n;++i)
fw(dis[i],0);
Heriko Deltana;
}
「欧拉路径」
UPD 2022.1.23
调了 \(\tt 114514\) 年,结果是答案栈开小了。
template<typename J>
I J Hmax(const J &x,const J &y) {
Heriko x>y?x:y;
}
CI MXX(1e5+5);
int n,m,into[MXX],outo[MXX],lst[MXX],ans[MXX<<1],s,t,cnt;
vector< pair<int,int> > r[MXX];
bitset<(MXX<<1)> vis;
void DFS(int x) {
for(int i(lst[x]);i<(int)r[x].size();i=Hmax(i+1,lst[x])) {
int y(r[x][i].first),id(r[x][i].second);
if(!vis[id]) {
vis[id]=1;
lst[x]=i+1;
DFS(y);
}
}
ans[++cnt]=x;
}
S main() {
Files();
fr(n),fr(m);
for(int i(1);i<=m;++i) {
int x,y;
fr(x),fr(y);
++outo[x],++into[y];
r[x].push_back(mkp(y,i));
}
int tot(0);
for(int i(1);i<=n;++i)
if(into[i]!=outo[i]) {
++tot;
if(into[i]==outo[i]-1)
s=i;
if(into[i]==outo[i]+1)
t=i;
}
if(tot!=0 and tot!=2) {
puts("No");
Heriko Deltana;
}
if(!tot)
s=t=1;
if(!s or !t) {
puts("No");
Heriko Deltana;
}
for(int i(1);i<=n;++i)
sort(r[i].begin(),r[i].end());
DFS(s);
for(int i(cnt);i;--i)
fw(ans[i],0);
Heriko Deltana;
}
「康托展开」
UPD 2022.1.23
#define lowbit(x) ((x)&(-x))
CI MXX(1e6+1),MOD(998244353);
int n;
LL t[MXX];
I void Add(int x,LL v) {
while(x<=n)
t[x]+=v,x+=lowbit(x);
}
I LL Query(int x) {
LL res(0);
while(x)
res+=t[x],x-=lowbit(x);
Heriko res;
}
LL pw[MXX],ans;
S main() {
Files();
fr(n);
for(int i(1);i<=n;++i)
Add(i,1);
pw[0]=1;
for(int i(1);i<=n;++i)
pw[i]=(pw[i-1]*i)%MOD;
for(int i(1);i<=n;++i) {
int x;
fr(x);
(ans+=((Query(x)-1)*pw[n-i])%MOD)%=MOD;
Add(x,-1);
}
fw(ans+1,1);
Heriko Deltana;
}
「威佐夫博弈」
UPD 2022.1.23
结论:若两堆物品的初始值为 \((n,m)\),且 \(m<n\),则使 \(z=n-m.\)
记
x=(LL)(((sqrt(5.0)+1.0)/2.0)*w);
若 \(m=x\),则先手必败,否则先手必胜。
LL n,m,w,x;
S main() {
Files();
fr(n),fr(m);
if(n<m)
swap(n,m);
w=n-m;
x=(LL)(((sqrt(5.0)+1.0)/2.0)*w);
if(x==m)
puts("0");
else
puts("1");
Heriko Deltana;
}
「莫队」
UPD 2022.1.23
CI MXX(5e4+1);
int n,m,k,a[MXX],sqn;
LL ans[MXX],co[MXX],cnt;
struct Node {
int l,r,id;
I bool operator < (const Node &co) const {
if(l/sqn!=co.l/sqn)
Heriko l<co.l;
if((l/sqn)&1)
Heriko r<co.r;
Heriko r>co.r;
}
}
q[MXX];
I void Add(int x) {
}
I void Del(int x) {
}
S main() {
Files();
fr(n),fr(m),fr(k),sqn=sqrt(n);
for(int i(1);i<=n;++i)
fr(a[i]);
for(int i(1);i<=m;++i)
fr(q[i].l),fr(q[i].r),q[i].id=i;
sort(q+1,q+1+m);
int lx(1),rx(0);
for(int i(1);i<=m;++i) {
while(lx<q[i].l)
Del(a[lx++]);
while(lx>q[i].l)
Add(a[--lx]);
while(rx<q[i].r)
Add(a[++rx]);
while(rx>q[i].r)
Del(a[rx--]);
ans[q[i].id]=cnt;
}
for(int i(1);i<=m;++i)
fw(ans[i],1);
Heriko Deltana;
}
「vector 存图遍历模板」
UPD 2022.1.23
CI MXX(1e6+1),NXX(1e5+1);
bitset<NXX> vis;
vector<int> r[NXX];
int n,m;
void DFS(int x) {
fw(x,0);
vis[x]=1;
int sz(r[x].size());
for(int i(0);i<sz;++i)
if(!vis[r[x][i]])
DFS(r[x][i]);
}
I void BFS() {
queue<int> q;
q.push(1),vis[1]=1;
while(q.size()) {
int y(q.front());
q.pop();
fw(y,0);
int sz(r[y].size());
for(int i(0);i<sz;++i)
if(!vis[r[y][i]])
q.push(r[y][i]),vis[r[y][i]]=1;
}
}
S main() {
Files();
fr(n),fr(m);
for(int i(1);i<=m;++i) {
int x,y;
fr(x),fr(y);
r[x].push_back(y);
}
for(int i(1);i<=n;++i)
std::sort(r[i].begin(),r[i].end());
DFS(1),puts("");
vis=0;
BFS(),puts("");
Heriko Deltana;
}
「Dinic」
UPD 2022.1.23
template <typename J>
I J Hmin(const J &x,const J &y) {
Heriko x<y?x:y;
}
CI MXX(5001),NXX(201),INF(998244353);
struct Node {
int nex,to;
LL val;
}
r[MXX<<1];
int cnt(1),head[NXX],now[NXX],n,m,s,t;
I void Add(int x,int y,LL z) {
r[++cnt]=(Node){head[x],y,z},head[x]=cnt;
r[++cnt]=(Node){head[y],x,0},head[y]=cnt;
}
LL dis[NXX],ans;
bitset<NXX> vis;
I bool BFS() {
mst(dis,0);
queue<int> q;
q.push(s);
dis[s]=1,now[s]=head[s];
while(q.size()) {
int x(q.front());
q.pop();
for(int i(head[x]);i;i=r[i].nex) {
if(r[i].val and !dis[r[i].to]) {
int y(r[i].to);
q.push(y);
now[y]=head[y],dis[y]=dis[x]+1;
if(y==t)
Heriko Romanno;
}
}
}
Heriko Deltana;
}
LL Dinic(int x,LL flow) {
if(x==t)
Heriko flow;
LL rst(flow),k;
for(int i(now[x]);i and rst;i=r[i].nex) {
int y(r[i].to);
if(r[i].val and dis[y]==dis[x]+1) {
k=Dinic(y,Hmin(rst,r[i].val));
if(!rst)
Heriko flow;
if(!k)
dis[y]=0;
r[i].val-=k,r[i^1].val+=k,rst-=k;
}
now[x]=i;
}
Heriko flow-rst;
}
S main() {
// Files();
fr(n),fr(m),fr(s),fr(t);
for(int i(1);i<=m;++i) {
int x,y;
LL z;
fr(x),fr(y),fr(z);
Add(x,y,z);
}
LL flow(0);
while(BFS())
while((flow=Dinic(s,INF)))
ans+=flow;
fw(ans,1);
Heriko Deltana;
}
「Tarjan求强连通分量」
UPD 2022.1.23
template <typename J>
I J Hmin(const J &x,const J &y) {
Heriko x<y?x:y;
}
CI MXX(100001),NXX(10001);
struct Node {
int nex,to;
}
r[MXX];
int rcnt,head[NXX];
I void Add(int x,int y) {
r[++rcnt]=(Node){head[x],y};
head[x]=rcnt;
}
int dfn[NXX],low[NXX],cnt,stak[NXX],top,tot,c[NXX];
bitset<NXX> vis;
vector<int> v[NXX];
void Tarjan(int x) {
dfn[x]=low[x]=++cnt;
stak[++top]=x,vis[x]=1;
for(int i(head[x]);i;i=r[i].nex) {
int y(r[i].to);
if(!dfn[y])
Tarjan(y),low[x]=Hmin(low[x],low[y]);
else if(vis[y])
low[x]=Hmin(low[x],dfn[y]);
}
if(dfn[x]==low[x]) {
++tot;
int tmp(0);
while(tmp!=x) {
tmp=stak[top--];
vis[tmp]=0;
c[tmp]=tot;
v[tot].push_back(tmp);
}
}
}
int n,m;
S main() {
// Files();
fr(n),fr(m);
for(int i(1);i<=m;++i) {
int x,y;
fr(x),fr(y);
Add(x,y);
}
for(int i(1);i<=n;++i)
if(!dfn[i])
Tarjan(i);
fw(tot,1);
for(int i(1);i<=n;++i) {
int x(c[i]);
if(vis[x])
continue;
vis[x]=1;
std::sort(v[x].begin(),v[x].end());
int sz(v[x].size());
for(int j(0);j<sz;++j)
fw(v[x][j],0);
puts("");
}
Heriko Deltana;
}
「珂朵莉树」
直接把我 CF896C 的代码拿过来了。
UPD 2022.1.23
I LL FstPow(LL x,LL y,LL p) {
LL res(1);
x%=p;
while(y) {
if(y&1)
(res*=x)%=p;
(x*=x)%=p;
y>>=1;
}
Heriko res;
}//其实这个快速幂没啥用,只是下面的 Query 的时候有用到,和 ODT 本身关系不大。
struct Node {
LL l,r;
mutable LL v;
Node(LL l,LL r=0,LL v=0) : l(l),r(r),v(v) {}
I bool operator < (const Node &co) const {
Heriko l<co.l;
}
};
set<Node> s;
I auto Split(LL pos) {
auto it(s.lower_bound(Node(pos)));
if(it!=s.end() and it->l==pos)
Heriko it;
--it;
if(it->r<pos)
Heriko s.end();
LL l(it->l),r(it->r),v(it->v);
s.erase(it);
s.insert(Node(l,pos-1,v));
Heriko s.insert(Node(pos,r,v)).first;
}
I void Assign(LL l,LL r,LL x) {
auto itr(Split(r+1)),itl(Split(l));
s.erase(itl,itr);
s.insert(Node(l,r,x));
}
I void Add(LL l,LL r,LL x) {
auto itr(Split(r+1)),itl(Split(l));
for(auto it(itl);it!=itr;++it)
it->v+=x;
}
struct Rank {
LL val,cnt;
Rank(LL val,LL cnt) : val(val),cnt(cnt) {}
I bool operator < (const Rank &co) const {
Heriko val<co.val;
}
};
I LL QueryRank(LL l,LL r,LL x) {
auto itr(Split(r+1)),itl(Split(l));
vector<Rank> v;
for(auto it(itl);it!=itr;++it)
v.push_back(Rank(it->v,it->r-it->l+1));
sort(v.begin(),v.end());
LL i(0);
for(;i<(LL)v.size();++i)
if(v[i].cnt<x)
x-=v[i].cnt;
else
Heriko v[i].val;
Heriko v[i].val;
}
I LL QueryVal(LL l,LL r,LL x,LL y) {
auto itr(Split(r+1)),itl(Split(l));
LL res(0);
for(auto it(itl);it!=itr;++it)
res=(res+FstPow(it->v,x,y)*(it->r-it->l+1)%y)%y;
Heriko res;
}
「平面最近点对」
\(O(n \log^2 n)\) 的做法。
UPD 2022.1.23
template<typename J>
I J Hmin(const J &x,const J &y) {
Heriko x<y?x:y;
}
CI MXX(2e5+1);
const double INF(1e12);
I bool CMP(const pair<double,double> &a,const pair<double,double> &b) {
Heriko a.second<b.second;
}
I double Dist(const pair<double,double> &a,const pair<double,double> &b) {
Heriko sqrt((long double)(a.first-b.first)*(a.first-b.first)+(long double)(a.second-b.second)*(a.second-b.second));
}
int n;
pair<double,double> a[MXX],tmp[MXX];
double Merge(int l,int r) {
if(l==r)
Heriko INF;
int mid((l+r)>>1),top(0);
double dis(INF);
dis=Hmin(Merge(l,mid),Merge(mid+1,r));
for(int i(l);i<=r;++i)
if(fabs(a[mid].first-a[i].first)<dis)
tmp[++top]=a[i];
std::sort(tmp+1,tmp+1+top,CMP);
for(int i(1);i<=top;++i)
for(int j(i+1);j<=top;++j) {
if(tmp[j].second-tmp[i].second>=dis)
break;
dis=Hmin(dis,Dist(tmp[i],tmp[j]));
}
Heriko dis;
}
S main() {
Files();
fr(n);
for(int i(1);i<=n;++i)
scanf("%lf%lf",&a[i].first,&a[i].second);
std::sort(a+1,a+1+n);
double ans(Merge(1,n));
printf("%.4lf",ans);
Heriko Deltana;
}