模板库
缺省源
头文件
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int main()
{
}
火车头
#pragma GCC optimize(3)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)
fread/fwrite
char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return x*f;
}
void write(long long x)
{
if(x>9)write(x/10);
*O++=x%10+'0';
}//fwrite(obuf,O-obuf,1,stdout);
图论
最短路(Dijkstra)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1e5+10,M=2e5+10;
int head[N],ver[M],nxt[M],tot=0,edge[M];
void add(int x,int y,int z)
{
ver[++tot]=y;
edge[tot]=z;
nxt[tot]=head[x];
head[x]=tot;
}
int dis[N];bool vis[N];
void dij(int s)
{
priority_queue<pii> que;
que.push(mp(0,s));
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
while(!que.empty())
{
int x=que.top().se;que.pop();
if(vis[x])continue;
vis[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i],z=edge[i];
if(dis[x]+z<dis[y])
{
dis[y]=dis[x]+z;
que.push(mp(-dis[y],y));
}
}
}
}
int main()
{
int n=read(),m=read(),s=read();
for(int i=1;i<=m;i++){int u=read(),v=read(),w=read();add(u,v,w);}
dij(s);
for(int i=1;i<=n;i++)printf("%d ",dis[i]);
}
最短路(SPFA)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1e4+10,M=5e5+10;
int head[N],ver[M],nxt[M],tot=0,edge[M];
void add(int x,int y,int z)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
edge[tot]=z;
}
int dis[N];bool vis[N];
void spfa(int s)
{
queue<int> que;que.push(s);
memset(dis,0x3f,sizeof(dis));dis[s]=0;
while(!que.empty())
{
int x=que.front();que.pop();
vis[x]=0;
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i],z=edge[i];
if(dis[x]+z<dis[y])
{
dis[y]=dis[x]+z;
if(!vis[y])vis[y]=1,que.push(y);
}
}
}
}
int main()
{
int n=read(),m=read(),s=read();
for(int i=1;i<=m;i++){int u=read(),v=read(),w=read();add(u,v,w);}
spfa(s);for(int i=1;i<=n;i++)printf("%d ",dis[i]==0x3f3f3f3f?0x7fffffff:dis[i]);
return 0;
}
最大流
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=210,M=1e4+10,inf=0x3f3f3f3f;
int head[N],ver[M],nxt[M],tot=1,edge[M];
void add(int x,int y,int z)
{
ver[++tot]=y;
edge[tot]=z;
nxt[tot]=head[x];
head[x]=tot;
}
int s,t,dis[N],cur[N];bool vis[N];
bool bfs()
{
memcpy(cur,head,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));dis[s]=0;
queue<int> que;que.push(s);
while(!que.empty())
{
int x=que.front();que.pop();
vis[x]=0;
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i],z=edge[i];
if(dis[x]+1<dis[y]&&z)
{
dis[y]=dis[x]+1;
if(!vis[y])
{
vis[y]=1;
que.push(y);
}
}
}
}
return dis[t]!=inf;
}
int dfs(int x,int limit)
{
if(x==t||!limit)return limit;
int flow=0,rlow=0;
for(int &i=cur[x];i;i=nxt[i])
{
int y=ver[i],z=edge[i];
if(dis[y]==dis[x]+1)
{
if(rlow=dfs(y,min(limit,z)))
{
flow+=rlow,limit-=rlow;
edge[i]-=rlow,edge[i^1]+=rlow;
if(!limit)break;
}
}
}
return flow;
}
signed main()
{
int n=read(),m=read();s=read(),t=read();
for(int i=1;i<=m;i++){int u=read(),v=read(),w=read();add(u,v,w),add(v,u,0);}
ll ans=0;
while(bfs())ans+=dfs(s,inf);
printf("%lld",ans);
}
//zzt qwq
最小费用最大流
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=5e3+10,M=1e5+10,inf=0x3f3f3f3f;
int head[N],ver[M],nxt[M],tot=1,edge[M],cost[M];
bool vis[N];
void add(int x,int y,int z,int c)
{
ver[++tot]=y,edge[tot]=z,cost[tot]=c;
nxt[tot]=head[x],head[x]=tot;
}
int dis[N],cur[N];
bool spfa(int s,int t)
{
memset(dis,0x3f,sizeof(dis));
memcpy(cur,head,sizeof(head));
queue<int> que;que.push(s),dis[s]=0;
while(!que.empty())
{
int x=que.front();que.pop();
vis[x]=0;
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i],z=edge[i],c=cost[i];
if(z&&dis[x]+c<dis[y])
{
dis[y]=dis[x]+c;
if(!vis[y])vis[y]=1,que.push(y);
}
}
}
return dis[t]!=inf;
}
int res=0;
int dfs(int x,int t,int limit)
{
// printf("dfs(%d, %d, %d)\n",x,t,limit);
if(x==t||!limit)return limit;
int flow=0,rlow=0;vis[x]=1;
for(int &i=cur[x];i;i=nxt[i])
{
int y=ver[i],z=edge[i],c=cost[i];
if(z&&!vis[y]&&dis[x]+c==dis[y])
{
rlow=dfs(y,t,min(limit,z));
if(rlow)flow+=rlow,limit-=rlow,edge[i]-=rlow,edge[i^1]+=rlow,res+=rlow*c;
if(!limit)break;
}
}
vis[x]=0;
return flow;
}
int dinic(int s,int t)
{
int ans=0;
while(spfa(s,t))
{
// printf("hello!\n");
int x=0;
while(x=dfs(s,t,inf))ans+=x;
}
return ans;
}
int main()
{
int n=read(),m=read(),s=1,t=n;
for(int i=1;i<=m;i++)
{
int x=read(),y=read(),z=read(),c=read();
add(x,y,z,c),add(y,x,0,-c);
}
int ans=dinic(s,t);
printf("%d %d\n",ans,res);
return 0;
}
//zzt qwq
三元环计数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1e5+10,M=2e5+10;
int head[N],ver[M],nxt[M],tot=0;
void add(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
int u[M],v[M],deg[N],vis[N];
int main()
{
int n=read(),m=read();
for(int i=1;i<=m;i++)
{
u[i]=read(),v[i]=read();
deg[u[i]]++,deg[v[i]]++;
}
for(int i=1;i<=m;i++)
{
if(deg[u[i]]>deg[v[i]])add(u[i],v[i]);
else if(deg[u[i]]<deg[v[i]])add(v[i],u[i]);
else add(max(u[i],v[i]),min(u[i],v[i]));
}
int ans=0;
for(int x=1;x<=n;x++)
{
for(int i=head[x];i;i=nxt[i]){int y=ver[i];vis[y]=x;}
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i];
for(int j=head[y];j;j=nxt[j])
{
int z=ver[j];
if(vis[z]==x)ans++;
}
}
}
printf("%d\n",ans);
return 0;
}
//zzt qwq
最小生成树(Borůvka)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=2e5+10;
struct dsu{
int sz[N],fa[N];
void init(int n){for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1;}
int getf(int x){return fa[x]==x?x:fa[x]=getf(fa[x]);}
void mg(int x,int y)
{
if(getf(x)==getf(y))return;
x=getf(x),y=getf(y);
sz[y]+=sz[x];
fa[x]=y;
}
}B;
vector<pii> v[N];
//first:edge, second:ver
void add(int x,int y,int z){v[x].pb(mp(z,y));}
int now[N],pos[N],n,m,mn[N],p;
int boruvka()
{
int ans=0;bool f=1;
while(f)
{
f=0;
for(int i=1;i<=n;i++)pos[i]=-1,mn[i]=1e9;
for(int x=1;x<=n;x++)
{
int fa=B.getf(x);
for(int j=now[x];j<(int)v[x].size();j++)
{
now[x]=j;
int y=v[x][j].se,z=v[x][j].fi;
if(B.getf(y)==fa)continue;
if(pos[fa]==-1||z<mn[fa])mn[fa]=z,pos[fa]=y;
break;
}
}
for(int i=1;i<=n;i++)
{
if(pos[i]==-1)continue;
if(B.getf(i)==B.getf(pos[i]))continue;
B.mg(i,pos[i]);
ans+=mn[i];
f=1;
}
}
return B.sz[B.getf(1)]==n?ans:-1;
}
int main()
{
n=read(),m=read();B.init(n);
for(int i=1;i<=m;i++)
{
int x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
for(int i=1;i<=n;i++)sort(v[i].begin(),v[i].end());
int ans=boruvka();
if(~ans)printf("%d\n",ans);
else puts("orz");
return 0;
}
最小生成树(Kruskal)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=5010,M=2e5+10;
struct dsu{
int fa[N];
void init(int n){for(int i=1;i<=n;i++)fa[i]=i;}
int getf(int x){return fa[x]==x?x:fa[x]=getf(fa[x]);}
void mg(int x,int y){fa[getf(y)]=getf(x);}
}B;
struct Edge{
int u,v,w;
}e[M];
bool cmp(Edge x,Edge y){return x.w<y.w;}
int main()
{
int n=read(),m=read(),cnt=0,ans=0;B.init(n);
for(int i=1;i<=m;i++){int u=read(),v=read(),w=read();e[i]=Edge{u,v,w};}
sort(e+1,e+m+1,cmp);
for(int i=1;i<=m;i++)
{
int u=e[i].u,v=e[i].v,w=e[i].w;
if(B.getf(u)==B.getf(v))continue;
B.mg(u,v),ans+=w,cnt++;
}
if(cnt!=n-1)puts("orz");
else printf("%d\n",ans);
return 0;
}
数据结构
线段树合并
//P3224 永无乡
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1e5+10;
int rt[N],pos[N];
struct sgt{
struct seg{
int ls,rs,sum;
seg(){ls=rs=sum=0;}
}t[N<<5];
int tot;
sgt(){tot=0;}
int modify(int l,int r,int x,int d)
{
int p=++tot;
if(l==r){t[p].sum+=d;return p;}
int mid=(l+r)>>1;
if(x<=mid)t[p].ls=modify(l,mid,x,d);
else t[p].rs=modify(mid+1,r,x,d);
t[p].sum=t[t[p].ls].sum+t[t[p].rs].sum;
return p;
}
int mg(int p,int q,int l,int r)
{
if(!p||!q)return p|q;
if(l==r){t[p].sum+=t[q].sum;return p;}
int mid=(l+r)>>1;
t[p].ls=mg(t[p].ls,t[q].ls,l,mid);
t[p].rs=mg(t[p].rs,t[q].rs,mid+1,r);
t[p].sum=t[t[p].ls].sum+t[t[p].rs].sum;
return p;
}
int query(int p,int l,int r,int k)
{
if(t[p].sum<k)return -1;
if(l==r)return l;int mid=(l+r)>>1;
if(t[t[p].ls].sum>=k)return query(t[p].ls,l,mid,k);
else return query(t[p].rs,mid+1,r,k-t[t[p].ls].sum);
}
}T;
int p[N];
struct dsu{
int fa[N];
void init(int n){for(int i=1;i<=n;i++)fa[i]=i;}
int getf(int x){return fa[x]==x?x:fa[x]=getf(fa[x]);}
void mg(int x,int y){fa[getf(y)]=getf(x);}
}B;
int main()
{
// freopen("1.out","w",stdout);
int n=read(),m=read();
for(int i=1;i<=n;i++)p[i]=read(),pos[p[i]]=i;
for(int i=1;i<=n;i++)rt[i]=T.modify(1,n,p[i],1);
B.init(n);
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
x=B.getf(x),y=B.getf(y);
if(B.getf(x)==B.getf(y))continue;
rt[x]=T.mg(rt[x],rt[y],1,n);
B.mg(x,y);
}
int Q=read();
while(Q--)
{
char s[3];scanf("%s",s);
if(s[0]=='Q')
{
int x=read(),k=read();
x=B.getf(x);
int tmp=T.query(rt[x],1,n,k);
if(~tmp)printf("%d\n",pos[tmp]);
else puts("-1");
}
else
{
int x=read(),y=read();
x=B.getf(x),y=B.getf(y);
if(B.getf(x)==B.getf(y))continue;
rt[x]=T.mg(rt[x],rt[y],1,n);
B.mg(x,y);
}
}
return 0;
}
莫队
//P4462
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=1e5+10;
int a[N],k,cnt[N],ans,Ans[N],sum[N];
void del(int x){ans-=cnt[x^k];cnt[x]--;}
void add(int x){ans+=cnt[x^k];cnt[x]++;}
struct query
{
int l,r,bl,pos;
query(){}
query(int ll,int rr,int bb,int pp){l=ll;r=rr;bl=bb;pos=pp;}
}q[N];
bool cmp(query x,query y){return x.bl!=y.bl?x.l<y.l:(x.bl&1)?x.r<y.r:x.r>y.r;}
int main()
{
int n,m;scanf("%d%d%d",&n,&m,&k);
int t=sqrt(n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]^a[i];
for(int i=1;i<=m;i++)
{
int l,r;scanf("%d%d",&l,&r);
q[i]=query(l-1,r,(l-1)/t+1,i);
}
sort(q+1,q+m+1,cmp);
int l=0,r=-1;
for(int i=1;i<=m;i++)
{
int ll=q[i].l,rr=q[i].r;
while(l<ll)del(sum[l++]);
while(l>ll)add(sum[--l]);
while(r<rr)add(sum[++r]);
while(r>rr)del(sum[r--]);
Ans[q[i].pos]=ans;
}
for(int i=1;i<=m;i++) printf("%d\n",Ans[i]);
return 0;
}
主席树
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=2e5+10;
int a[N],t[N],rt[N];
int tot=0;
struct president
{
struct node
{
int ls,rs,sum;
node(){ls=rs=sum=0;}
}t[N<<5];
int build(int l,int r)
{
int p=++tot;
if(l==r)return p;
int mid=(l+r)/2;
t[p].ls=build(l,mid);
t[p].rs=build(mid+1,r);
return p;
}
int modify(int pre,int l,int r,int x)
{
int p=++tot;
t[p]=t[pre];
if(l==r)
{
t[p].sum++;
return p;
}
int mid=(l+r)/2;
if(x<=mid)t[p].ls=modify(t[pre].ls,l,mid,x);
else t[p].rs=modify(t[pre].rs,mid+1,r,x);
t[p].sum=t[t[p].ls].sum+t[t[p].rs].sum;
return p;
}
int query(int u,int v,int l,int r,int k)
{
int sum=t[t[v].ls].sum-t[t[u].ls].sum;
if(l==r)return l;
int mid=(l+r)/2;
if(sum>=k)return query(t[u].ls,t[v].ls,l,mid,k);
else return query(t[u].rs,t[v].rs,mid+1,r,k-sum);
}
}T;
int main()
{
int n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
memcpy(t,a,sizeof(a));int c=n;
sort(t+1,t+c+1);c=unique(t+1,t+c+1)-t-1;
for(int i=1;i<=n;i++)a[i]=lower_bound(t+1,t+c+1,a[i])-t;
rt[0]=T.build(1,c);
for(int i=1;i<=n;i++)rt[i]=T.modify(rt[i-1],1,c,a[i]);
for(int i=1;i<=m;i++)
{
int l=read(),r=read(),k=read();
printf("%d\n",t[T.query(rt[l-1],rt[r],1,c,k)]);
}
return 0;
}
轻重链剖分
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=1e5+10,M=2e5+10;
int head[N],ver[M],nxt[M],tot=0,mod;
void add(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
int dfn[N],num,top[N],sz[N],son[N],fa[N],dep[N],pos[N],a[N];
void dfs(int x)
{
// printf("x=%d\n",x);
sz[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i];if(dep[y])continue;
dep[y]=dep[x]+1,fa[y]=x;
dfs(y),sz[x]+=sz[y];
if(!son[x]||(sz[y]>sz[son[x]]))son[x]=y;
}
}
void dfs1(int x,int t)
{
dfn[x]=++num,pos[dfn[x]]=x,top[x]=t;
if(son[x])dfs1(son[x],t);
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i];
if(y==fa[x]||y==son[x])continue;
dfs1(y,y);
}
}
struct sgt{
struct seg{
int l,r;
int add,sum;
}t[N<<2];
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
t[p].add=0;
if(l==r)return t[p].sum=a[pos[l]],void();
int mid=(l+r)>>1;
build(p*2,l,mid),build(p*2+1,mid+1,r);
t[p].sum=t[p*2].sum+t[p*2+1].sum,t[p].sum%=mod;
}
void pd(int p)
{
if(t[p].add)
{
t[p*2].add+=t[p].add,t[p*2].add%=mod;
t[p*2+1].add+=t[p].add,t[p*2+1].add%=mod;
t[p*2].sum+=1ll*(t[p*2].r-t[p*2].l+1)*t[p].add%mod,t[p*2].sum%=mod;
t[p*2+1].sum+=1ll*(t[p*2+1].r-t[p*2+1].l+1)*t[p].add%mod,t[p*2+1].sum%=mod;
t[p].add=0;
}
}
int query(int p,int l,int r)
{
if(l<=t[p].l&&t[p].r<=r)return t[p].sum;
pd(p);int mid=(t[p].l+t[p].r)>>1,ans=0;
if(l<=mid)ans+=query(p*2,l,r),ans%=mod;
if(r>mid)ans+=query(p*2+1,l,r),ans%=mod;
return ans;
}
void modify(int p,int l,int r,int d)
{
if(l<=t[p].l&&t[p].r<=r)
{
t[p].sum+=1ll*(t[p].r-t[p].l+1)*d%mod,t[p].sum%=mod;
t[p].add+=d,t[p].add%=mod;
return;
}
pd(p);int mid=(t[p].l+t[p].r)>>1;
if(l<=mid)modify(p*2,l,r,d);
if(r>mid)modify(p*2+1,l,r,d);
t[p].sum=t[p*2].sum+t[p*2+1].sum,t[p].sum%=mod;
}
}T;
void modify(int x,int y,int d)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]>=dep[fy])
{
T.modify(1,dfn[fx],dfn[x],d);
x=fa[fx];
}
else
{
T.modify(1,dfn[fy],dfn[y],d);
y=fa[fy];
}
fx=top[x],fy=top[y];
}
T.modify(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),d);
}
int query(int x,int y)
{
int ans=0,fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]>=dep[fy])
{
ans+=T.query(1,dfn[fx],dfn[x]),ans%=mod;
x=fa[fx];
}
else
{
ans+=T.query(1,dfn[fy],dfn[y]),ans%=mod;
y=fa[fy];
}
fx=top[x],fy=top[y];
}
ans+=T.query(1,min(dfn[x],dfn[y]),max(dfn[x],dfn[y])),ans%=mod;
return ans;
}
int main()
{
int n=read(),m=read(),rt=read();mod=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<n;i++){int u=read(),v=read();add(u,v),add(v,u);}
dep[rt]=1,dfs(rt),dfs1(rt,rt),T.build(1,1,n);
while(m--)
{
int pos=read();
if(pos==1){int u=read(),v=read(),w=read();modify(u,v,w);}
else if(pos==2){int u=read(),v=read();printf("%d\n",query(u,v));}
else if(pos==3){int x=read(),d=read();T.modify(1,dfn[x],dfn[x]+sz[x]-1,d);}
else {int x=read();printf("%d\n",T.query(1,dfn[x],dfn[x]+sz[x]-1));}
}
}
//zzt qwq
普通平衡树(FHQ Treap)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e5+10;
int ch[N][2],val[N],pri[N],sz[N],cnt=0;
void maintain(int x){sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];}
int build(int v)
{
val[++cnt]=v;
pri[cnt]=rand();
sz[cnt]=1;
return cnt;
}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(pri[x]<pri[y])
{
ch[x][1]=merge(ch[x][1],y);
maintain(x);
return x;
}
else
{
ch[y][0]=merge(x,ch[y][0]);
maintain(y);
return y;
}
}
void split(int now,int k,int &x,int &y)
{
if(!now)x=y=0;
else
{
if(val[now]<=k)x=now,split(ch[now][1],k,ch[x][1],y);
else y=now,split(ch[now][0],k,x,ch[y][0]);
maintain(now);
}
}
int kth(int now,int k)
{
while(114514)
{
if(sz[ch[now][0]]>=k)now=ch[now][0];
else if(sz[ch[now][0]]+1==k)return val[now];
else k-=sz[ch[now][0]]+1,now=ch[now][1];
}
}
int main()
{
int n=read(),rt=0,x,y,z;
for(int i=1;i<=n;i++)
{
int p=read(),v=read();
if(p==1)//insert
{
split(rt,v-1,x,y);
rt=merge(merge(x,build(v)),y);
}
else if(p==2)//delete
{
split(rt,v,x,z);
split(x,v-1,x,y);
y=merge(ch[y][0],ch[y][1]);
rt=merge(merge(x,y),z);
}
else if(p==3)//rank
{
split(rt,v-1,x,y);
printf("%d\n",sz[x]+1);
rt=merge(x,y);
}
else if(p==4)//kth
printf("%d\n",kth(rt,v));
else if(p==5)//pre
{
split(rt,v-1,x,y);
printf("%d\n",kth(x,sz[x]));
rt=merge(x,y);
}
else//nxt
{
split(rt,v,x,y);
printf("%d\n",kth(y,1));
rt=merge(x,y);
}
}
return 0;
}
普通平衡树(Splay)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5;
int rt,tot,sz[N+10],ch[N+10][2],fa[N+10],cnt[N+10],val[N+10];
void maintain(int x) {sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];}
void clear(int x) {sz[x]=ch[x][0]=ch[x][1]=fa[x]=cnt[x]=val[x]=0;}
int get(int x) {return ch[fa[x]][1]==x;}
void rorate(int x)
{
int y=fa[x],z=fa[y],w=get(x);
ch[y][w]=ch[x][w^1];
fa[ch[x][w^1]]=y;
ch[x][w^1]=y;
fa[y]=x;
fa[x]=z;
if(z) ch[z][y==ch[z][1]]=x;
maintain(y);
maintain(x);
}
void splay(int x)
{
for(int f=fa[x];f=fa[x],f;rorate(x))
if(fa[f]) rorate(get(f)==get(x)?f:x);
rt=x;
}
void ins(int k)
{
if(!rt)
{
val[++tot]=k;
cnt[tot]++;
rt=tot;
maintain(rt);
return;
}
int cur=rt,f=0;
while(1)
{
if(val[cur]==k)
{
cnt[cur]++;
maintain(cur);
maintain(f);
splay(cur);
break;
}
f=cur;
cur=ch[cur][val[cur]<k];
if(!cur)
{
val[++tot]=k;
cnt[tot]++;
fa[tot]=f;
ch[f][val[f]<k]=tot;
maintain(tot);
maintain(f);
splay(tot);
break;
}
}
}
int rk(int k)
{
int cur=rt,res=0;
while(1)
{
if(k<val[cur]) cur=ch[cur][0];
else
{
res+=sz[ch[cur][0]];
if(val[cur]==k)
{
splay(cur);
return res+1;
}
res+=cnt[cur];
cur=ch[cur][1];
}
}
}
int kth(int k)
{
int cur=rt;
while(1)
{
if(k<=sz[ch[cur][0]] && ch[cur][0]) cur=ch[cur][0];
else
{
k-=sz[ch[cur][0]]+cnt[cur];
if(k<=0)
{
splay(cur);
return val[cur];
}
cur=ch[cur][1];
}
}
}
int pre()
{
int cur=ch[rt][0];
while(ch[cur][1]) cur=ch[cur][1];
return cur;
}
int nxt()
{
int cur=ch[rt][1];
while(ch[cur][0]) cur=ch[cur][0];
return cur;
}
void del(int k)
{
rk(k);
if(cnt[rt]>1)
{
cnt[rt]--;
maintain(rt);
return;
}
if(!ch[rt][0] && !ch[rt][1])
{
clear(rt);
rt=0;
return;
}
if(!ch[rt][0])
{
int cur=rt;
rt=ch[rt][1];
fa[rt]=0;
clear(cur);
return;
}
if(!ch[rt][1])
{
int cur=rt;
rt=ch[rt][0];
fa[rt]=0;
clear(cur);
return;
}
int cur=rt,x=pre();
splay(x);
fa[ch[cur][1]]=x;
ch[x][1]=ch[cur][1];
clear(cur);
maintain(rt);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int p,x;
scanf("%d %d",&p,&x);
if(p==1) ins(x);
else if(p==2) del(x);
else if(p==3) printf("%d\n",rk(x));
else if(p==4) printf("%d\n",kth(x));
else if(p==5)
{
ins(x);
printf("%d\n",val[pre()]);
del(x);
}
else
{
ins(x);
printf("%d\n",val[nxt()]);
del(x);
}
}
return 0;
}
文艺平衡树(FHQ Treap)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1e5+10;
int ch[N][2],val[N],pri[N],sz[N],cnt=0,tag[N];
void maintain(int x){sz[x]=1+sz[ch[x][0]]+sz[ch[x][1]];}
void pd(int p)
{
if(!tag[p])return;
swap(ch[p][0],ch[p][1]);
if(ch[p][0])tag[ch[p][0]]^=1;
if(ch[p][1])tag[ch[p][1]]^=1;
tag[p]=0;
}
int build(int v)
{
val[++cnt]=v;
pri[cnt]=rand();
sz[cnt]=1;
return cnt;
}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(pri[x]<pri[y])
{
pd(x);
ch[x][1]=merge(ch[x][1],y);
maintain(x);
return x;
}
else
{
pd(y);
ch[y][0]=merge(x,ch[y][0]);
maintain(y);
return y;
}
}
void split(int now,int k,int &x,int &y)
{
if(!now)x=y=0;
else
{
pd(now);
if(k<=sz[ch[now][0]])y=now,split(ch[now][0],k,x,ch[y][0]);
else x=now,split(ch[now][1],k-sz[ch[now][0]]-1,ch[x][1],y);
maintain(now);
}
}
void print(int p)
{
if(!p)return;
pd(p);
print(ch[p][0]);
printf("%d ",val[p]);
print(ch[p][1]);
}
int main()
{
int n=read(),rt=0,x,y,z,m=read();
for(int i=1;i<=n;i++)rt=merge(rt,build(i));
for(int i=1;i<=m;i++)
{
int l=read(),r=read();
split(rt,l-1,x,y);
split(y,r-l+1,y,z);
tag[y]^=1;
rt=merge(merge(x,y),z);
}
print(rt);
return 0;
}
三维偏序(CDQ分治)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=2e5+10;
struct node{
int x,y,z,c,pos;
node(){x=y=z=c=pos=0;}
}a[N],b[N];
bool cmp(node a,node b){return a.x!=b.x?a.x<b.x:(a.y!=b.y?a.y<b.y:a.z<b.z);}
bool cmp1(node a,node b){return a.y!=b.y?a.y<b.y:a.z<b.z;}
//bool cmp2(node a,node b){return a.pos<b.pos;}
int m;
struct bit{
int c[N];
bit(){memset(c,0,sizeof(c));}
int query(int x){int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;}
void modify(int x,int d){for(;x<=m;x+=x&-x)c[x]+=d;}
}T;
int f[N];
void cdq(int l,int r)
{
if(l==r)return;
int mid=(l+r)>>1;
cdq(l,mid),cdq(mid+1,r);
sort(a+l,a+mid+1,cmp1),sort(a+mid+1,a+r+1,cmp1);
int j=l;
for(int i=mid+1;i<=r;i++)
{
while(j<=mid&&a[j].y<=a[i].y)T.modify(a[j].z,a[j].c),j++;
f[a[i].pos]+=T.query(a[i].z);
}
for(int i=l;i<j;i++)T.modify(a[i].z,-a[i].c);
}
int Ans[N];
int main()
{
int nn=read(),n=0;m=read();
for(int i=1;i<=nn;i++)b[i].x=read(),b[i].y=read(),b[i].z=read();
sort(b+1,b+nn+1,cmp);
a[n=1]=b[1],a[1].c=1;
for(int i=2;i<=nn;i++)
{
if(a[n].x==b[i].x&&a[n].y==b[i].y&&a[n].z==b[i].z)a[n].c++;
else a[++n]=b[i],a[n].c=1;
}
for(int i=1;i<=n;i++)a[i].pos=i;
cdq(1,n);
for(int i=1;i<=n;i++)f[a[i].pos]+=a[i].c-1;
// sort(a+1,a+n+1,cmp2);
// for(int i=1;i<=n;i++)printf("(%d, %d, %d), cnt=%d, f=%d\n",a[i].x,a[i].y,a[i].z,a[i].c,f[i]);
for(int i=1;i<=n;i++)Ans[f[a[i].pos]]+=a[i].c;
for(int i=0;i<nn;i++)printf("%d\n",Ans[i]);
return 0;
}
//zzt qwq
笛卡尔树
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1e7+10;
int p[N],st[N],top=0,ls[N],rs[N];
int main()
{
int n=read();
for(int i=1;i<=n;i++)p[i]=read();
for(int i=1;i<=n;i++)
{
int k=top;
while(k&&p[i]<p[st[k]])k--;
if(k)rs[st[k]]=i;
if(k<top)ls[i]=st[k+1];
st[++k]=i,top=k;
}
ll ans1=0,ans2=0;
for(int i=1;i<=n;i++)ans1^=1ll*i*(ls[i]+1),ans2^=1ll*i*(rs[i]+1);
printf("%lld %lld\n",ans1,ans2);
return 0;
}
//zzt qwq
数学
线性筛
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
bitset<100000010>vis;
const int N=5e7+10,maxn=1e8;
int pri[N],tot=0;
void init()
{
for(int i=2;i<=maxn;i++)
{
if(!vis[i])
pri[++tot]=i;
for(int j=1;j<=tot&&pri[j]*i<=maxn;j++)
{
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
}
int main()
{
init();
int n=read(),q=read();
while(q--)
{
int k=read();
printf("%d\n",pri[k]);
}
}
高斯消元&行列式求值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=110;
const double eps=1e-4;
double a[N][N];
int main()
{
int n=read();
for(int i=1;i<=n;i++)for(int j=1;j<=n+1;j++)a[i][j]=read();
for(int i=1;i<=n;i++)
{
int p=i;
for(int j=i+1;j<=n;j++)if(fabs(a[j][i])>=fabs(a[p][i]))p=j;
for(int j=1;j<=n+1;j++)swap(a[i][j],a[p][j]);
if(fabs(a[i][i])<=eps)return puts("No Solution"),0;
for(int j=i+1;j<=n;j++)
{
double r=a[j][i]/a[i][i];
for(int k=1;k<=n+1;k++)a[j][k]-=a[i][k]*r;
}
for(int k=i+1;k<=n+1;k++)a[i][k]/=a[i][i];
a[i][i]=1;
}
for(int i=n-1;i;i--)for(int j=i+1;j<=n;j++)a[i][n+1]-=a[j][n+1]*a[i][j];
for(int i=1;i<=n;i++)printf("%.2lf\n",a[i][n+1]);
}
//zzt qwq
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=610;
int n,mod;
struct mat{
int a[N][N];
mat(){memset(a,0,sizeof(a));}
int det()
{
int ans=1;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
while(a[i][i])
{
int r=a[j][i]/a[i][i];
for(int k=1;k<=n;k++)a[j][k]-=1ll*r*a[i][k]%mod,a[j][k]=(a[j][k]+mod)%mod;
for(int k=1;k<=n;k++)swap(a[i][k],a[j][k]);
ans=1ll*ans*(mod-1)%mod;
}
ans=1ll*ans*(mod-1)%mod;
for(int k=1;k<=n;k++)swap(a[i][k],a[j][k]);
}
}
for(int i=1;i<=n;i++)ans=1ll*ans*a[i][i]%mod;
return ans;
}
}x;
int main()
{
n=read(),mod=read();
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)x.a[i][j]=read();
printf("%d\n",x.det());
return 0;
}
//zzt qwq
CRT/EXCRT
太丑了,有时间重新写一份
拉格朗日插值
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int mod=998244353;
int qpow(int a,int n)
{
int ans=1;
while(n)
{
if(n&1)ans=1ll*a*ans%mod;
a=1ll*a*a%mod;
n>>=1;
}
return ans;
}
const int N=2e3+10;
int x[N],y[N];
int main()
{
int n=read(),k=read();
for(int i=1;i<=n;i++)x[i]=read(),y[i]=read();
int ans=0;
for(int i=1;i<=n;i++)
{
int s2=1,s1=1;
for(int j=1;j<=n;j++)
{
if(i==j)continue;
s1=(k-x[j]+mod)%mod*1ll*s1%mod;
s2=(x[i]-x[j]+mod)%mod*1ll*s2%mod;
}
ans+=1ll*s1*qpow(s2,mod-2)%mod*y[i]%mod,ans%=mod;
}
printf("%d",ans);
return 0;
}
AND/OR/XOR 卷积
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0)putchar('-'),n=-n;
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=1<<17,mod=998244353,inv2=(mod+1)>>1;
int a[N],b[N],c[N],n;
int ta[N],tb[N];
void fwt_and()
{
memcpy(ta,a,sizeof(a)),memcpy(tb,b,sizeof(b));
for(int i=0;i<n;i++)
{
for(int s=0;s<(1<<n);s++)
{
if(!(s&(1<<i)))continue;
a[s^(1<<i)]+=a[s],b[s^(1<<i)]+=b[s],a[s^(1<<i)]%=mod,b[s^(1<<i)]%=mod;
}
}
for(int s=0;s<(1<<n);s++)c[s]=1ll*a[s]*b[s]%mod;
for(int i=0;i<n;i++)
{
for(int s=0;s<(1<<n);s++)
{
if(!(s&(1<<i)))continue;
c[s^(1<<i)]-=c[s],c[s^(1<<i)]=(c[s^(1<<i)]+mod)%mod;
}
}
memcpy(a,ta,sizeof(ta)),memcpy(b,tb,sizeof(tb));
}
void fwt_or()
{
memcpy(ta,a,sizeof(a)),memcpy(tb,b,sizeof(b));
for(int i=0;i<n;i++)
{
for(int s=0;s<(1<<n);s++)
{
if(s&(1<<i))continue;
a[s^(1<<i)]+=a[s],b[s^(1<<i)]+=b[s],a[s^(1<<i)]%=mod,b[s^(1<<i)]%=mod;
}
}
for(int s=0;s<(1<<n);s++)c[s]=1ll*a[s]*b[s]%mod;
for(int i=0;i<n;i++)
{
for(int s=0;s<(1<<n);s++)
{
if(s&(1<<i))continue;
c[s^(1<<i)]-=c[s],c[s^(1<<i)]=(c[s^(1<<i)]+mod)%mod;
}
}
memcpy(a,ta,sizeof(ta)),memcpy(b,tb,sizeof(tb));
}
void fwt_xor()
{
memcpy(ta,a,sizeof(a)),memcpy(tb,b,sizeof(b));
for(int i=1;i<(1<<n);i<<=1)
{
for(int j=0;j<(1<<n);j+=(i<<1))
{
for(int s=j;s<j+i;s++)
{
int x=a[s],y=a[s+i];
a[s]=(x+y)%mod,a[s+i]=(x-y+mod)%mod;
}
}
}
for(int i=1;i<(1<<n);i<<=1)
{
for(int j=0;j<(1<<n);j+=(i<<1))
{
for(int s=j;s<j+i;s++)
{
int x=b[s],y=b[s+i];
b[s]=(x+y)%mod,b[s+i]=(x-y+mod)%mod;
}
}
}
for(int s=0;s<(1<<n);s++)c[s]=1ll*a[s]*b[s]%mod;
for(int i=1;i<(1<<n);i<<=1)
{
for(int j=0;j<(1<<n);j+=(i<<1))
{
for(int s=j;s<j+i;s++)
{
int x=c[s],y=c[s+i];
c[s]=(x+y)%mod,c[s+i]=(x-y+mod)%mod;
c[s]=1ll*c[s]*inv2%mod,c[s+i]=1ll*c[s+i]*inv2%mod;
}
}
}
memcpy(a,ta,sizeof(ta)),memcpy(b,tb,sizeof(tb));
}
int main()
{
n=read();
for(int i=0;i<(1<<n);i++)a[i]=read();
for(int i=0;i<(1<<n);i++)b[i]=read();
fwt_or();for(int i=0;i<(1<<n);i++)printf("%d ",c[i]);puts("");
fwt_and();for(int i=0;i<(1<<n);i++)printf("%d ",c[i]);puts("");
fwt_xor();for(int i=0;i<(1<<n);i++)printf("%d ",c[i]);puts("");
return 0;
}
//zzt qwq
子集卷积
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0)putchar('-'),n=-n;
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=1<<20,mod=1e9+9;
int a[N],n,f[25][N],g[25][N],h[25][N],pop[N];
void fwt_or(int *a,int tp)
{
for(int i=0;i<n;i++)
{
for(int s=0;s<(1<<n);s++)
{
if(s&(1<<i))continue;
if(tp==1)a[s^(1<<i)]+=a[s],a[s^(1<<i)]%=mod;
else a[s^(1<<i)]+=mod-a[s],a[s^(1<<i)]%=mod;
}
}
}
int main()
{
for(int i=1;i<N;i++)pop[i]=pop[i>>1]+(i&1);
n=read();
for(int i=0;i<(1<<n);i++)f[pop[i]][i]=read();
for(int i=0;i<(1<<n);i++)g[pop[i]][i]=read();
for(int i=0;i<=n;i++)fwt_or(f[i],1),fwt_or(g[i],1);
for(int i=0;i<=n;i++)for(int j=0;j+i<=n;j++)for(int s=0;s<(1<<n);s++)
h[i+j][s]+=1ll*f[i][s]*g[j][s]%mod,h[i+j][s]%=mod;
for(int i=0;i<=n;i++)fwt_or(h[i],-1);
for(int i=0;i<(1<<n);i++)printf("%d ",h[pop[i]][i]);
return 0;
}
//zzt qwq
字符串
KMP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1000010;
int nxt[N],la,lb;
char a[N],b[N];
int main()
{
scanf("%s%s",a+1,b+1);
la=strlen(a+1);
lb=strlen(b+1);
for(int i=2,j=0;i<=lb;i++)
{
while(j&&b[i]!=b[j+1])j=nxt[j];
if(b[j+1]==b[i])j++;
nxt[i]=j;
}
for(int i=1,j=0;i<=la;i++)
{
while(j>0&&b[j+1]!=a[i])j=nxt[j];
if(b[j+1]==a[i])j++;
if(j==lb)
{
printf("%d\n",i-lb+1);
j=nxt[j];
}
}
for(int i=1;i<=lb;i++)printf("%d ",nxt[i]);
return 0;
}
AC自动机
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
const int N=1e6+10;
struct ACAM{
int tot,tr[N][26],e[N],fail[N];
ACAM(){tot=0;memset(tr,0,sizeof(tr)),memset(e,0,sizeof(e)),memset(fail,0,sizeof(fail));}
void ins(char *s)
{
int u=0;
for(int i=1;s[i];i++)
{
if(!tr[u][s[i]-'a'])tr[u][s[i]-'a']=++tot;
u=tr[u][s[i]-'a'];
}
e[u]++;
}
void getfail()
{
queue<int> que;
for(int i=0;i<26;i++)if(tr[0][i])que.push(tr[0][i]);
while(!que.empty())
{
int x=que.front();que.pop();
for(int i=0;i<26;i++)
{
if(tr[x][i])fail[tr[x][i]]=tr[fail[x]][i],que.push(tr[x][i]);
else tr[x][i]=tr[fail[x]][i];
}
}
}
int query(char *s)
{
int ans=0,p=0;
for(int i=1;s[i];i++)
{
int x=s[i]-'a';
p=tr[p][x];
for(int j=p;j&&~e[j];j=fail[j])ans+=e[j],e[j]=-1;
}
return ans;
}
}T;
char s[N];
int main()
{
int n=read();
for(int i=1;i<=n;i++)scanf("%s",s+1),T.ins(s);
T.getfail();scanf("%s",s+1);
printf("%d\n",T.query(s));
return 0;
}
SA
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
void write(int n)
{
if(n<0){putchar('-');n=-n;}
if(n>9)write(n/10);
putchar(n%10^48);
}
const int N=2e6+10;
char s[N];int id[N],cnt[N],sa[N],rk[N],old[N];
bool cmp(int x,int y,int w){return old[x]==old[y]&&old[x+w]==old[y+w];}
int main()
{
scanf("%s",s+1);int n=strlen(s+1),m=300;
for(int i=1;i<=n;i++)cnt[rk[i]=s[i]]++;
for(int i=1;i<=m;i++)cnt[i]+=cnt[i-1];
for(int i=n;i;i--)sa[cnt[rk[i]]--]=i;
for(int p=0,w=1;;m=p,w<<=1)
{
p=0;for(int i=n;i>n-w;i--)id[++p]=i;
for(int i=1;i<=n;i++)if(sa[i]>w)id[++p]=sa[i]-w;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)cnt[rk[id[i]]]++;
for(int i=1;i<=m;i++)cnt[i]+=cnt[i-1];
for(int i=n;i;i--)sa[cnt[rk[id[i]]]--]=id[i];
memcpy(old,rk,sizeof(rk));
p=0;for(int i=1;i<=n;i++)rk[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;
if(p==n)break;
}
for(int i=1;i<=n;i++)printf("%d ",sa[i]);
}