1.筛\(phi\)
\(logn\)求少数\(phi\)
inline int phi(R int x){
R int res=x,tmp=x;
for(R int i=2;i*i<=x;i++){
if(tmp%i==0)res=res*(i-1)/i;
while(tmp%i==0)tmp/=i;
}
if(tmp>1)res=res*(tmp-1)/tmp;
return res;
}
线性求\(phi\)
inline void getphi(R int n){
vis[1]=0;
for(R int i=2;i<=n;i++){
if(!vis[i]){
prime[++tot]=i;
phi[i]=i-1;
}
for(R int j=1;j<=tot&&i*prime[j]<=n;j++){
vis[prime[j]*i]=1;
if(i%prime[j]==0){
phi[prime[j]*i]=phi[i]*prime[j];break;
}
else phi[prime[j]*i]=phi[i]*(priem[j]-1);
}
}
}
2.ST表
inline void pre(){
mn[0]=-1;
for(R int i=1;i<=n;i++){
mn[i]=((i&(i-1))==0)? mn[i-1]+1:mn[i-1];
stmax[i][0]=a[i];
}
for(R int j=1;j<=mn[n];j++)
for(R int i=1;i+(1<<j)-1<=n;i++)
stmax[i][j]=max(stmax[i][j-1],stmax[i+(1<<(j-1))][j-1]);
}
inline int getmax(R int l,R int r){
R int k=mn[r-l+1];
return max(stmax[l][k],stmax[r-(1<<k)+1][k]);
}
int main(){
read(n);read(m);
for(R int i=1;i<=n;i++)read(a[i]);
pre();
for(R int i=1;i<=m;i++){
read(l);read(r);
printf("%d\n",getmax(l,r));
}
return 0;
}
3.高斯消元
read(n);
for(R int i=1;i<=n;i++)
for(R int j=1;j<=n+1;j++)
scanf("%lf",&mp[i][j]);
for(R int i=1;i<=n;i++){
R int mx=i;
for(R int j=i+1;j<=n;j++)
if(fabss(mp[mx][i])<fabss(mp[j][i]))mx=i;
if(mx!=i)swap(mp[mx],mp[i]);
if(fabss(mp[i][i])>eps){
R double div=mp[i][i];
for(R int j=i;j<=n+1;j++)
mp[i][j]/=div;
for(R int j=1;j<=n;j++){
if(i==j)continue;
div=mp[j][i];
for(R int k=i;k<=n+1;k++)
mp[j][k]-=div*mp[i][k];
}
}
}
for(R int i=1;i<=n;i++){
R int cnt=1;
while(fabss(mp[i][cnt])<eps&&cnt<=n+1)cnt++;
if(cnt==n+1)pd_nojie=1;
if(cnt>n+1)pd_wuqiong=1;
}
if(pd_nojie||pd_wuqiong){
printf("No Solution\n");
return 0;
}
ans[n]=mp[n][n+1];
for(R int i=n-1;i>=1;i--){
ans[i]=mp[i][n+1];
for(R int j=i+1;j<=n;j++)
ans[i]-=mp[i][j]*ans[j];
}
for(R int i=1;i<=n;i++)
printf("%.2lf\n",ans[i]);
4.悬线法
for(R int i=1;i<=n;i++){
for(R int j=1;j<=m;j++){
read(mp[i][j]);
up[i][j]=1;
l[i][j]=r[i][j]=j;
}
}
for(R int i=1;i<=n;i++)
for(R int j=2;j<=m;j++)
if(mp[i][j]!=mp[i][j-1])
l[i][j]=l[i][j-1];
for(R int i=1;i<=n;i++)
for(R int j=m-1;j>=1;j--)
if(mp[i][j]!=mp[i][j+1])
r[i][j]=r[i][j+1];
for(R int i=1;i<=n;i++){
for(R int j=1;j<=m;j++){
if(i>1&&mp[i][j]!=mp[i-1][j]){
l[i][j]=max(l[i][j],l[i-1][j]);
r[i][j]=min(r[i][j],r[i-1][j]);
up[i][j]=up[i-1][j]+1;
}
R int a=r[i][j]-l[i][j]+1;
R int b=min(a,up[i][j]);
ans1=max(ans1,b*b);
ans2=max(ans2,a*up[i][j]);
}
}
5.nim游戏
tmp=0;
read(n);
for(R int i=1;i<=n;i++)
read(x),tmp^=x;
if(tmp)printf("Yes\n");
else printf("No\n");
6.线段树双lazy
#define ls(o) o<<1
#define rs(o) o<<1|1
#define up(o) t[o]=(t[ls(o)]+t[rs(o)])%mod
inline void build(R int o,R int l,R int r){
mul[o]=1;add[o]=0;
if(l==r){
t[o]=a[l]%mod;
return;
}
R int mid=(l+r)>>1;
build(ls(o),l,mid);
build(rs(o),mid+1,r);
up(o);
}
inline void push_down(R int o,R int l,R int r){
if(mul[o]!=1){
t[ls(o)]=(mul[o]*t[ls(o)])%mod;
t[rs(o)]=(mul[o]*t[rs(o)])%mod;
add[ls(o)]=(add[ls(o)]*mul[o])%mod;
add[rs(o)]=(add[rs(o)]*mul[o])%mod;
mul[ls(o)]=(mul[o]*mul[ls(o)])%mod;
mul[rs(o)]=(mul[o]*mul[rs(o)])%mod;
mul[o]=1;
}
R int mid=(l+r)>>1;
if(add[o]){
t[ls(o)]=(t[ls(o)]+add[o]*(mid-l+1))%mod;
t[rs(o)]=(t[rs(o)]+add[o]*(r-mid))%mod;
add[ls(o)]=(add[ls(o)]+add[o])%mod;
add[rs(o)]=(add[rs(o)]+add[o])%mod;
add[o]=0;
}
}
inline void update_add(R int o,R int nl,R int nr,R int l,R int r,R ll k){
if(nl<=l&&nr>=r){
t[o]=(t[o]+(r-l+1)*k)%mod;
add[o]=(add[o]+k)%mod;
return;
}
push_down(o,l,r);
R int mid=(l+r)>>1;
if(nl<=mid)update_add(ls(o),nl,nr,l,mid,k);
if(nr>mid)update_add(rs(o),nl,nr,mid+1,r,k);
up(o);
}
inline void update_mul(R int o,R int nl,R int nr,R int l,R int r,R ll k){
if(nl<=l&&nr>=r){
t[o]=t[o]*k%mod;
add[o]=add[o]*k%mod;
mul[o]=mul[o]*k%mod;
return;
}
push_down(o,l,r);
R int mid=(l+r)>>1;
if(nl<=mid)update_mul(ls(o),nl,nr,l,mid,k);
if(nr>mid)update_mul(rs(o),nl,nr,mid+1,r,k);
up(o);
}
7.有理数取余(附加快速幂)
char A[N],B[N];
ll a,b;
inline ll ksm(R ll x,R ll y){
ll res=1;
while(y){
if(y&1)res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
int main(){
scanf("%s%s",A+1,B+1);
R int n=strlen(A+1);
R int m=strlen(B+1);
for(R int i=1;i<=n;i++)
a=(a*10+A[i]-'0')%mod;
for(R int i=1;i<=m;i++)
b=(b*10+B[i]-'0')%mod;
if(!b)printf("Angry!\n");
else printf("%lld\n",a*ksm(b,mod-2)%mod);
return 0;
}
8.割点(割顶)
inline void tarjan(R int x){
R int rd=0;
dfn[x]=low[x]=++num;
for(R int i=h[x];i;i=edge[i].nex){
R int xx=edge[i].to;
if(!dfn[xx]){
fa[xx]=fa[x];
tarjan(xx);
low[x]=min(low[x],low[xx]);
if(low[xx]>=dfn[x]&&x!=fa[x])cut[x]=1;
if(x==fa[x])rd++;
}
low[x]=min(low[x],dfn[xx]);
}
if(x==fa[x]&&rd>=2)cut[x]=1;
}
int main(){
read(n);read(m);
for(R int i=1,u,v;i<=m;i++)
read(u),read(v),add(u,v),add(v,u);
for(R int i=1;i<=n;i++)fa[i]=i;
for(R int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
R int now=0;
for(R int i=1;i<=n;i++)
if(cut[i])ans[++now]=i;
printf("%d\n",now);
for(R int i=1;i<=now;i++)printf("%d ",ans[i]);
return 0;
}
9.缩点
inline void tarjan(R int x){
vis[x]=1;
sta[++top]=x;
dfn[x]=low[x]=++num;
for(R int i=h[x];i;i=edge[i].nex){
R int xx=edge[i].to;
if(!dfn[xx]){
tarjan(xx);
low[x]=min(low[x],low[xx]);
}
else if(vis[xx])low[x]=min(low[x],dfn[xx]);
}
if(dfn[x]==low[x]){
cnt++;
R int now=-1;
while(now!=x){
now=sta[top];
top--;
col[now]=cnt;
sum[cnt]+=val[now];
vis[now]=0;
}
}
}
10.裴蜀定理
scanf("%d",&n);
scanf("%d",&ans);
ans=abs(ans);
for(R int i=2;i<=n;i++){
scanf("%d",&x);
ans=gcd(ans,abs(x));
}
printf("%d",ans);
11.负环
inline bool spfa(R int s){
queue<int> q;
for(R int i=1;i<=n;i++)dist[i]=INF,vis[i]=0;
q.push(s);vis[s]=1;dist[s]=0;cnt[s]++;
while(!q.empty()){
R int x=q.front();q.pop();vis[x]=0;
cnt[x]++;
if(cnt[x]>=n)return 1;
for(R int i=h[x];i;i=edge[i].nex){
R int xx=edge[i].to;
if(dist[xx]>dist[x]+edge[i].dis){
dist[xx]=dist[x]+edge[i].dis;
if(!vis[xx]){
vis[xx]=1;
q.push(xx);
}
}
}
}
return 0;
}