NOIP前的模板

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;
}

猜你喜欢

转载自www.cnblogs.com/ZAGER/p/9859932.html