板子
板子
快读
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*10+ch-48;ch=getchar();}
return x*f;
}
欧拉筛
int n,cnt,vis[40005],prime[4005],phi[40005];
void euler(){
//phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[++cnt]=i;
//phi[i]=i-1;
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){
//phi[i*prime[j]]=phi[i]*prime[j];
break;
}
//phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
//"//"后的为欧拉函数
同余
\(a\equiv b(\bmod m)=m|a-b=a-b=km\)
\(p=\lfloor \frac p i \rfloor \times +(p\%i)\)
\(p \equiv0 \pmod p\)
\(\lfloor \frac p i \rfloor \times i+(p\%i) \equiv 0 \pmod p\)
\(\lfloor \frac p i \rfloor + (p\%i)\times i^{-1}\equiv 0 \pmod p\)
\(\lfloor \frac p i \rfloor (p\%i)^{-1}+ i^{-1}\equiv 0 \pmod p\)
\(i^{-1} \equiv (p-\lfloor \frac p i \rfloor)\times(p\%i)^{-1} \pmod p\)
矩阵
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
struct Mat{
#define int long long
int a[105][105],r,c;
Mat(int _r=0,int _c=0){
r=_r,c=_c;memset(a,0,sizeof(a));
if(c==0) c=r;
}
void unit(){
memset(a,0,sizeof(a));
for(int i=1;i<=r;i++) a[i][i]=1;
}
Mat operator+(const Mat&t)const{
Mat ans=*this;
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
ans.a[i][j]+=t.a[i][j];
}
}
return ans;
}
Mat operator*(const Mat&t)const{
Mat ans(r,t.c);
int n=r,m=t.c;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=1;k<=c;k++){
ans.a[i][j]=(ans.a[i][j]+a[i][k]*t.a[k][j])%mod;
}
}
}
return ans;
}
Mat qpow(int b){
Mat ans(r,c),a=*this;
ans.unit();
while(b){
if(b&1) ans=ans*a;
a=a*a;
b>>=1;
}
return ans;
}
void out(){
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
cout<<a[i][j]<<" ";
}
cout<<"\n";
}
}
void input(){
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
cin>>a[i][j];
}
}
}
#undef int
};
链式前向星
struct node{
int to,nxt,w;
}edge[N<<1];
int head[N],cnt=1;
void add(int u,int v,int w){
edge[cnt].to=v;
edge[cnt].nxt=head[u];
edge[cnt].w=w;
head[u]=cnt++;
}
bfs
void bfs(){
qx.push(sx);qy.push(sy);
vis[sx][sy]=1;
while(!qx.empty()){
int x=qx.front(),y=qy.front();
qx.pop();qy.pop();
for(int i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(tx>n||tx<1||ty>m||ty<1) continue;
if(vis[tx][ty]) continue;
vis[tx][ty]=1;
qx.push(tx);qy.push(ty);
}
}
}
最短路(Dijkstra)
const int INF=0x3f3f3f3f,N=2e5+5;
int n,m,s,t,cnt=1,dis[N],vis[N],head[N];
struct e{
int to,nxt,w;
}edge[N];
struct node{
int v,w;
const bool operator<(const node &x)const{
return w>x.w;
}
};
priority_queue<node> q;
void dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[s]=0;q.push({s,0});
while(!q.empty()){
int u=q.top().v;q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to,w=edge[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push({v,dis[v]});
}
}
}
}
最短路(SPFA)
queue<int> q;
void spfa(){
memset(dis,0x3f,sizeof(dis));
dis[s]=0;q.push(s);vis[s]=1;
while(!q.empty()){
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to,w=edge[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(!vis[v]) q.push(v);
}
}
}
}
最小生成树(Kruskal)
int fa[5005],n,m,f,ans;
struct node{
int x,y,z;
}a[200005];
bool cmp(node x,node y){
return x.z<y.z;
}
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void add(int x,int y,int k){
int f1=find(x),f2=find(y);
if(f1!=f2) fa[f1]=f2,n--,ans+=a[k].z;
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i].x>>a[i].y>>a[i].z;
}
sort(a+1,a+m+1,cmp);
for(int i=1;i<=n;i++)
fa[i]=i;
for(int i=1;i<=m;i++){
add(a[i].x,a[i].y,i);
if(n==1) break;
}
return 0;
}
最小生成树(Prim)
void Prim(){
for(int i=1;i<=n;i++) dis[i]=0x3f3f3f3f;
dis[1]=0; q.push({1,0});
while(!q.empty()){
int u=q.top().v;q.pop();
if(vis[u]) continue;
vis[u]=1;ans+=dis[u];sum++;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to,w=edge[i].w;
if(vis[v]) continue;
if(dis[v]>w){
dis[v]=w;
q.push({v,w});
}
}
}
}
std容器清空
template<typename T>
void clear(T &x){
T tmp;
swap(x,tmp);
}
ST表
int n,m,f[100005][30];
int query(int l,int r){
int k=log2(r-l+1);
return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&f[i][0]);
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r));
}
return 0;
}
线段树
const int N=1e5+5;
struct tree{
int l,r,sum,laz;
}t[N<<2];
int n,m,a[N];
int ls(int p){
return p<<1;
}
int rs(int p){
return p<<1|1;
}
void pushup(int p){
t[p].sum=t[ls(p)].sum+t[rs(p)].sum;
}
void pushdown(int p){
t[ls(p)].sum+=t[p].laz*(t[ls(p)].r-t[ls(p)].l+1);
t[rs(p)].sum+=t[p].laz*(t[rs(p)].r-t[rs(p)].l+1);
t[ls(p)].laz+=t[p].laz;
t[rs(p)].laz+=t[p].laz;
t[p].laz=0;
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(t[p].l==t[p].r){
t[p].sum=a[l];
return ;
}
int mid=l+r>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
pushup(p);
}
void update(int p,int l,int r,int k){
if(t[p].l>=l&&t[p].r<=r){
t[p].sum+=(t[p].r-t[p].l+1)*k;
t[p].laz+=k;
return ;
}
pushdown(p);
int mid=t[p].l+t[p].r>>1;
if(l<=mid) update(ls(p),l,r,k);
if(mid<r) update(rs(p),l,r,k);
pushup(p);
}
int query(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r){
return t[p].sum;
}
pushdown(p);
int ans=0;
int mid=t[p].l+t[p].r>>1;
if(l<=mid) ans+=query(ls(p),l,r);
if(mid<r) ans+=query(rs(p),l,r);
pushup(p);
return ans;
}
FHQ Treap
struct tree{
int ls,rs,val,rnk,sz;
}t[N];
int tot,root;
void update(int p){
t[p].sz=t[t[p].ls].sz+t[t[p].rs].sz+1;
}
int add(int val){
t[++tot].sz=1;
t[tot].val=val;
t[tot].rnk=rand();
return tot;
}
void split(int p,int &a,int &b,int val){
if(p==0){
a=b=0;
return ;
}
if(t[p].val<=val){
a=p;
split(t[p].rs,t[p].rs,b,val);
}
else{
b=p;
split(t[p].ls,a,t[p].ls,val);
}
update(p);
return ;
}
void merge(int &p,int a,int b){
if(a==0||b==0){
p=a+b;
return ;
}
if(t[a].rnk<t[b].rnk){
p=a;
merge(t[a].rs,t[a].rs,b);
}
else{
p=b;
merge(t[b].ls,a,t[b].ls);
}
update(p);
return ;
}
void insert(int &p,int val){
int a=0,b=0,cur=add(val);
split(p,a,b,val);
merge(a,a,cur);
merge(p,a,b);
return ;
}
void del(int &p,int val){
int a=0,b=0,z=0;
split(p,a,b,val);
split(a,a,z,val-1);
merge(z,t[z].ls,t[z].rs);
merge(a,a,z);
merge(p,a,b);
return ;
}
int find_num(int p,int x){
while(t[t[p].ls].sz+1!=x){
if(t[t[p].ls].sz>=x)
p=t[p].ls;
else{
x-=t[t[p].ls].sz+1;
p=t[p].rs;
}
}
return t[p].val;
}
int find_rank(int &p,int val){
int a=0,b=0;
split(p,a,b,val-1);
int tmp=t[a].sz+1;
merge(p,a,b);
return tmp;
}
int prev(int &p,int val){
int a=0,b=0;
split(p,a,b,val-1);
int tmp=find_num(a,t[a].sz);
merge(p,a,b);
return tmp;
}
int suf(int &p, int val){
int a=0,b=0;
split(p,a,b,val);
int tmp=find_num(b,1);
merge(p,a,b);
return tmp;
}
分块
const int N=1e6+5;
int a[N],b[N],l[1005],r[1005],belong[N],laz[1005];
int n,q,block,tot;
void build(){
block=(int)sqrt(n);tot=n/block;
if(n%block!=0) tot++;
for(int i=1;i<=n;i++){
belong[i]=(i-1)/block+1;b[i]=a[i];
}
for(int i=1;i<=tot;i++){
l[i]=(i-1)*block+1;r[i]=i*block;
}
r[tot]=n;
for(int i=1;i<=tot;i++){
sort(b+l[i],b+r[i]+1);
}
}
void change(int x,int y,int k){
if(belong[x]==belong[y]){
for(int i=x;i<=y;i++){
a[i]+=k;
}
for(int i=l[belong[x]];i<=r[belong[x]];i++){
b[i]=a[i];
}
sort(b+l[belong[x]],b+r[belong[x]]+1);
}
else{
for(int i=x;i<=r[belong[x]];i++){
a[i]+=k;
}
for(int i=l[belong[x]];i<=r[belong[x]];i++){
b[i]=a[i];
}
sort(b+l[belong[x]],b+r[belong[x]]+1);
for(int i=l[belong[y]];i<=y;i++){
a[i]+=k;
}
for(int i=l[belong[y]];i<=r[belong[y]];i++){
b[i]=a[i];
}
sort(b+l[belong[y]],b+r[belong[y]]+1);
for(int i=belong[x]+1;i<=belong[y]-1;i++){
laz[i]+=k;
}
}
}
int query(int x,int y,int k){
int ans=0;
if(belong[x]==belong[y]){
for(int i=x;i<=y;i++){
if(laz[belong[x]]+a[i]>=k) ans++;
}
return ans;
}
else{
for(int i=x;i<=r[belong[x]];i++){
if(laz[belong[x]]+a[i]>=k) ans++;
}
for(int i=l[belong[y]];i<=y;i++){
if(laz[belong[y]]+a[i]>=k) ans++;
}
for(int i=belong[x]+1;i<=belong[y]-1;i++){
int ll=l[i],rr=r[i],sum=0;
while(ll<=rr){
int mid=ll+rr>>1;
if(b[mid]+laz[i]>=k) rr=mid-1,sum=r[i]-mid+1;
else ll=mid+1;
}
ans+=sum;
}
return ans;
}
}
最近公共祖先(LCA) (树剖版)
const int N=5e5+5;
int fa[N],top[N],dep[N],sz[N],wc[N];
void dfs1(int u,int f){
fa[u]=f;sz[u]=1;dep[u]=dep[f]+1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==f) continue;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[wc[u]]) wc[u]=v;
}
}
void dfs2(int u,int Top){
top[u]=Top;
if(wc[u]) dfs2(wc[u],Top);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]||v==wc[u]) continue;
dfs2(v,v);
}
}
int qry(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]<dep[y]) return x;
return y;
}
Tarjan
const int N=1e5+5;
struct node{
int to,nxt;
}edge[N];
int head[N],cnt=1;
void add(int u,int v){
edge[cnt].to=v;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
int dfn[N],low[N],idx,sz[N],bel[N],tot;
bool ins[N];
stack<int> st;
void dfs(int u){
low[u]=dfn[u]=++tot;
st.push(u);
ins[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(!dfn[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}else if(ins[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
int v;++idx;
do{
v=st.top();st.pop();
bel[v]=idx;
ins[v]=0;
++sz[idx];
}while(v!=u);
}
}
字符串哈希
struct HASH{
int sed,mod,h[N],pw[N];
HASH(int ssed=128,int mmod=998244353){
sed=ssed,mod=mmod;
pw[0]=1;
for(int i=1;i<N;i++) pw[i]=pw[i-1]*1ll*sed%mod;
}
void make(string s){
h[0]=s[0]%mod;
for(int i=1;i<s.size();i++){
h[i]=(h[i-1]*1ll*sed%mod+s[i])%mod;
}
}
void make(char *s){
h[0]=s[0]%mod;
for(int i=1;s[i];i++){
h[i]=(h[i-1]*1ll*sed%mod+s[i])%mod;
}
}
int get(int L,int R){
if(!L) return h[R];
return (h[R]-h[L-1]*1ll*pw[R-L+1]%mod+mod)%mod;
}
int get(int R){
return h[R];
}
};
KMP
void getNxet(char P[]){
int i,j;//i遍历主串,j是border长度
//j也是前部分border的最后一个字符的下标
for(Next[i]=j=0,i=2;P[i];i++){
while(j&&P[i]!=P[j+1]) j=Next[j];//不相等跳border
if(P[i]==P[j+1]) j++;//相等border长度+1
Next[i]=j;//记录s[1~i]这个前缀的border
}
}
void KMP(char S[],char P[]){//主串S,模式串P
n=strlen(P+1);//获取模式串的长度
getNext(P);//先对模式串求每个前缀的border长度
int i,j,ans=0;
for(j=0,i=1;S[i];i++){//开始匹配
//j代表了模式串中匹配成功的长度
while(j&&S[i]!=P[j+1]) j=Next[j];//不相等跳border
if(S[i]==P[j+1]) j++;//相等匹配成功长度+1
if(j==n){//整个模式串都匹配成功
cout<<i-n+1<<"\n";//输出匹配成功的开头位置
j=Next[j];//允许重复跳border
//不允许重复j=0
}
}
}
int b[1000005];
string s1,s2;
int main(){
cin>>s1>>s2;
int len1=s1.size(),len2=s2.size(),j=0;
for(int i=1;i<len2;i++){
while(j>0&&s2[i]!=s2[j]) j=b[j-1];
if(s2[j]==s2[i]) j++;
b[i]=j;
} j=0;
for(int i=0;i<len1;i++){
while(j>0&&s1[i]!=s2[j]) j=b[j-1];
if(s2[j]==s1[i]) j++;
if(j==len2) j=b[j-1];
}
}
字典树
int trie[N][26],word[N],cnt[N];
string s;
int n,m,tot,ans;
void insert(string s){
int u=0,res=0;
int len=s.size();
for(int i=0;i<len;i++){
int a=s[i]-'a';
if(trie[u][a]==0){
trie[u][a]=++tot;
}
u=trie[u][a];
}
word[u]++;
}
manacher
int manacher(string &t){
string s="$|";
for(char c:t) s.push_back(c),s.push_back('|');
int n=s.size(),r=0,pos=0,ans=0;s+='!';
for(int i=1;i<n;i++){
p[i]=(r>i?min(p[2*pos-i],r-i):1);
while(s[i-p[i]]==s[i+p[i]]) p[i]++;
if(i+p[i]>r) r=i+p[i],pos=i;
ans=max(ans,p[i]-1);
}
return ans;
}

浙公网安备 33010602011771号