我这里列举了一些相比于之前整理的板子不太常用但有时候很有用的一些板子,以防忘记。
ST表,用于快速查询区间最值(O(nlogn)预处理O(1)查询)(但有线段树用什么ST表啊)。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int maxn=3e5+5; inline int read() { int ret=0,f=1; char c=getchar(); while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} while(c>='0'&&c<='9') {ret=ret*10+c-'0';c=getchar();} return ret*f; } int n,m; int num[maxn]; int d[maxn][23]; void make_st() { for(int j=1;j<=log2(n);j++) for(int i=1;i<=n;i++) { d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]); } } inline int ask_maxx(int l,int r) { int k=log2(r-l+1); return max(d[l][k],d[r-(1<<k)+1][k]); } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) { num[i]=read(); d[i][0]=num[i]; } make_st(); int a,b; while(m--) { a=read(),b=read(); printf("%d ",ask_maxx(a,b)); } return 0; }
归并排序求逆序对,可以用于求最小交换次数或连续序列和计数问题
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int maxn=4e4+5; int n,num[maxn]; int ans=0; int C[maxn]; void mergef(int l,int mid,int r) { int i=l,j=mid+1,k=l-1; while(i<=mid&&j<=r) { if(num[i]>num[j]) { ans+=mid-i+1; C[++k]=num[j++]; } else C[++k]=num[i++]; } while(i<=mid) C[++k]=num[i++]; while(j<=r) C[++k]=num[j++]; for(int p=l;p<=r;p++) num[p]=C[p]; } void mesort(int l,int r) { if(l==r) return; int mid=l+r>>1; mesort(l,mid); mesort(mid+1,r); mergef(l,mid,r); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&num[i]); } mesort(1,n); printf("%d ",ans); return 0; }
欧拉筛(线性筛),比埃筛快一点。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; const int N=10000000+5; const int M=7e5+5; bool nopr[N]; int prime[M]; int tot=0; void shai(int r) { nopr[0]=nopr[1]=1; for(int i=2;i<=r;i++) { if(!nopr[i]) prime[++tot]=i; for(int j=1;j<=tot;j++) { if(i*prime[j]>r) break; nopr[i*prime[j]]=1; if(!(i%prime[j])) break; } } } int n,m; int main() { scanf("%d%d",&n,&m); shai(n); int x; for(int i=1;i<=m;i++) { scanf("%d",&x); if(nopr[x]) printf("No "); else printf("Yes "); } return 0; }
快速幂。。没什么好说的吧。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long ll; ll n,m,k,s; ll mod; ll ksm(ll x,ll y) { ll ret=1; while(y) { if(y&1) ret*=x,ret%=mod; x*=x,x%=mod; y>>=1; } return ret; } int main() { scanf("%lld%lld%lld%lld",&n,&m,&k,&s); mod=n; ll ans=(s%mod+ksm(10,k)*m%mod)%mod; printf("%lld ",ans%mod); return 0; }
扩欧,求不定方程等
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long ll; ll xp,yp,m,n,L; void exgcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1; y=0; return; } exgcd(b,a%b,x,y); ll t=x; x=y; y=t-(a/b)*y; } ll gcd(ll a,ll b) { if(!b) return a; return gcd(b,a%b); } int main() { scanf("%lld%lld%lld%lld%lld",&xp,&yp,&m,&n,&L); if(m<n) swap(xp,yp),swap(m,n); ll a=m-n,b=L,c=yp-xp; ll d=gcd(a,b); if(c%d) {printf("Impossible ");return 0;} else { ll x,y; a/=d,b/=d,c/=d; exgcd(a,b,x,y); ll ans=c*x; ans=(ans%b+b)%b; printf("%lld ",ans); } return 0; }