码迷,mamicode.com
首页 > 其他好文 > 详细

CSP 前模板

时间:2019-11-12 19:48:36      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:reg   二分图   输出   lower   st表   因子   else   负数   线性筛   

快CSP了,放一下自己打的板子。

/*tarjan 缩点*/
void tarajn(int x)
{
    dfn[x]=low[x]=++cnt;zhan[++top]=x;
    vis[x]=1;
    for(int i=head[x];i;i=e[i].nt)
    {
        if(!dfn[e[i].to])
        {
            tarjan(e[i].to);
            low[x]=min(low[x],low[e[i].to]);
        }
        else if(vis[e[i].to])low[x]=min(low[x],dfn[e[i].to]);
    }
    if(dfn[x]==low[x])
    {
        int k;kuai++;
        do
        {
            k=zhan[top--];
            c[k]=kuai;
            vis[k]=0;
        }while(x!=k);
    }
}
/*快速幂*/
LL ksm(LL a,LL b,LL mod)
{
    LL res=1;
    for(;b;b>>=1,a=a*a%mod)if(b&1)res=res*a%mod;
    return res;
}
/*龟速乘*/
LL gsc(LL a,lLL b,LL mod)
{
    LL res=0;
    for(;b;b>>=1,a=(a+a)%mod)if(b&1)res=(res+a)%mod;
    return res;
}
/*线性筛素数*/
for(int i=2;i<=M;++i)
{
    if(!vis[i])prime[++tot]=i;
    for(int j=1;j<=tot&&prime[j]*i<=M;++j)
    {
        vis[prime[j]*i]=1;
        if(!(i%prime[j]))break;
    }
}
/*线性筛phi函数*/
phi[1]=1;
for(int i=2;i<=M;++i) 
{
    if(!vis[i]) prime[++tot]=i,phi[i]=i-1;
    for(int j=1;j<=tot&&i*p[j]<=M;++j) 
    {
        vis[i*prime[j]]=1;
        if(!(i%prime[j])) 
        {
            phi[i*prime[j]]=phi[i]*prime[j];
            break;
        }
        phi[i*prime[j]]=phi[i]*(prime[j]-1);
    }
} 
/*约数个数*/
/*
he表示i的约数个数  num表示i的最小素因子的个数
*/
he[1]=1;vis[1]=1;num[1]=1;
for(int i=2;i<=M;++i)
{
    if(!vis[i])
    {
        zhi[++tot]=i;
        he[i]=2;num[i]=1;
    }
    for(int j=1;j<=tot&&zhi[j]*i<=M;++j)
    {
        vis[zhi[j]*i]=1;
        if(!(i%zhi[j]))
        {
            num[i*zhi[j]]=num[i]+1;
            he[zhi[j]*i]=he[i]/(num[i]+1)*(num[i*zhi[j]]+1);
            break;
        }
        else 
        {
            num[i*zhi[j]]=1;
            he[zhi[j]*i]=he[zhi[j]]*he[i];
        }
    }
} 
/*约数和*/
/*
yh表示i的约数和 xh表示i的最小素因子的等比数列的和
*/
yh[1]=xh[1]=1;
for(register int i=2;i<=M;++i)
{
    if(!vis[i])
    {
        zhi[++tot]=i;
        yh[i]=i+1;xh[i]=i+1;
    }
    for(register int j=1;j<=tot&&zhi[j]*i<=M;++j)
    {
        vis[i*zhi[j]]=1;
        if(!(i%zhi[j]))
        {
            yh[i*zhi[j]]=yh[i]/xh[i]*(xh[i]*zhi[j]+1);
            xh[i*zhi[j]]=xh[i]*zhi[j]+1;
            break;
        }
        yh[i*zhi[j]]=yh[i]*yh[zhi[j]];
        xh[i*zhi[j]]=zhi[j]+1;
    }
}
for(register int i=1;i<=M;++i)
xh[i]=xh[i-1]+yh[i];
/*根号求phi*/
/*
a和m互质时,a^{phi(m)} == 1 mod m
b>=phi(m)时,a^b ==  a^{(b mod phi(m)) + phi(m)} mod m
*/
LL solve_phi(LL x)
{
    LL res=x;
    for(int i=2;i*i<=x;++i)
        if(!(x%i))
        {
            res=res-res/i;
            while(!(x%i))x/=i;
        }
    if(x!=1)res=res-res/x;
    return res;
}
/*DIJ单源最短路*/
struct dian
{
    int hao,dis;
    friend bool operator <(const dian &a,const dian &b)
    {return a.dis>b.dis;}
};
priority_queue<dian>q;
memset(dis,0x3f,sizeof dis);
dis[s]=0;
q.push(dian{s,0});
while(!q.empty())
{
    x=q.top().hao;q.pop();
    if(vis[x])continue;
    vis[x]=1;
    for(int i=head[x];i;i=e[i].nt)
        if(dis[e[i].to]>dis[x]+e[i].dis)
        {
            dis[e[i].to]=dis[x]+e[i].dis;
            q.push(dian{e[i].to,dis[e[i].to]});
        }
}
/*SPFA*/
memset(dis,0x3f,sizeof dis);
dis[s]=0;
q.push(s);vis[s]=1;
while(!q.empty())
{
    x=q.front;q.pop();vis[x]=0;
    for(int i=head[x];i;i=e[i].nt)
    {
        if(dis[e[i].to]>dis[x]+e[i].dis)
        {
            dis[e[i].to]=dis[x]+e[i].dis;
            if(!vis[e[i].to])
            {
                q.push(e[i].to);
                vis[e[i].to]=1;
            }
        }
    }
}
/*快读*/
inline int read()
{
    int res=0;char ch=getchar();bool XX=false;
    for(;!isdigit(ch);ch=getchar())(ch=='-')&&(XX=true);
    for(; isdigit(ch);ch=getchar())res=(res<<3)+(res<<1)+(ch^48);
    return XX?-res:res;
}
/*快输*/
/*注意不能输出负数和0!*/
void Write(LL x)
{
    if(!x)return;
    Write(x/10);
    putchar((x-x/10*10)+'0');
}
/*倍增求LCA*/
void yych(int x,int f)
{
    dep[x]=dep[f]+1;fa[x][0]=f;
    
    for(int i=1;(1<<i)<=dep[x];++i)
    fa[x][i]=fa[fa[x][i-1]][i-1];
    
    for(int i=head[x];i;i=e[i].nt)
    if(e[i].to!=f)yych(e[i].to,x);
}
int LCA(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    for(int i=21;i>=0;--i)
    if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];
    
    if(x==y)return x;
    
    for(int i=21;i>=0;--i)
    {
        if(fa[x][i]==fa[y][i])continue;
        x=fa[x][i];y=fa[y][i];
    }
    return fa[x][0];
}
/*树链剖分*/
void dfs1(int x)
{
    siz[x]=1;
    for(int i=head[x];i;i=e[i].nt)
    {
        if(e[i].to==fa[x])continue;
        dep[e[i].to]=dep[x]+1;
        fa[e[i].to]=x;
        dfs1(e[i].to);
        siz[x]+=siz[e[i].to];
        if(siz[e[i].to]>siz[son[x]])son[x]=e[i].to;
    }
}
void dfs2(int x,int t)
{
    dfn[x]=++cnt;
    a[cnt]=val[x];
    top[x]=t;
    if(son[x])dfs2(son[x],t);
    else return;
    for(int i=head[x];i;i=e[i].nt)
    {
        if(e[i].to==fa[x]||e[i].to==son[x])continue;
        dfs2(e[i].to,e[i].to);
    }
}
/*快速排序*/
void my_sort(int l,int r)
{
    int ix=l,jx=r,mid=num[(l+r)>>1];
    do
    {
        while(num[ix]<mid)ix++;
        while(num[jx]>mid)jx--;
        if(ix<=jx)swap(num[ix++],num[jx--]);    
    }while(ix<=jx);
    if(l<jx)my_sort(l,jx);
    if(ix<r)my_sort(ix,r);
}
/*快速排序找第k大数*/
int qsort(int l,int r,int k)
{
    if(l==r)return a[l];
    int now1=l,now2=r,mid=a[(l+r)>>1];
    do
    {
        while(a[now1]<mid) now1++;
        while(a[now2]>mid) now2--;
        if(now1<=now2) swap(a[now1++],a[now2--]);
    }while(now1<=now2);
    if(l<now2&&k<=(now2-l+1)) return qsort(l,now2,k);
    else if(now1<r&&k>(now1-l)) return qsort(now1,r,k-(now1-l));
    else return a[l+k-1];
}
/*扩展欧几里得*/
void EXGCD(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1;y=0;
        return;
    }
    EXGCD(b,a%b,x,y);
    int t=x;x=y;y=t-(a/b)*y;
}
/*中国剩余定理*/
/*a*m*t之和*/
cin>>n;
for(int i=1;i<=n;++i)scanf("%lld%lld",&p[i],&a[i]);
for(int i=1;i<=n;++i)M*=p[i];
for(int i=1;i<=n;++i)
{
    int l,k,j;
    m[i]=M/p[i];
    int lin=exgcd(m[i],p[i],l,j);
    (ans+=(a[i]*m[i]*l))%=M;
    ans=(ans+M)%M;
}
/*卢卡斯定理*/
/*L(n,m)==L(n/p,m/p)*C(n%p,m%p) (mod p)*/
LL lucas(LL n,LL m)
{
    if(!m)return 1;
    return lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod;
}
/*二分*/
l=0;r=***;
while(l<=r)
{
    int mid=(l+r)>>1;
    if(check(mid))ans=mid,r=mid-1;
    else l=mid+1;
}
cout<<ans;
/*lowbit*/
int lowbit(int x){return x&(-x);}
/*树状数组查询*/
int ask(int pos)
{
    int res=0;
    for(;pos;pos-=lowbit(pos))res+=tr[pos];
    return res;
}
/*树状数组修改*/
void add(int pos,int val)
{
    for(;pos<=n;pos+=lowbit(pos))tr[pos]+=val;
}
/*KMP*/
int k=0;nt[1]=0;
for(int i=2;i<=lenb;++i)
{
    while(k&&b[k+1]!=b[i])k=nt[k];
    if(b[k+1]==b[i])++k;
    nt[i]=k;
}
k=0;
for(int i=1;i<=lena;++i)
{
    while(k&&b[k+1]!=a[i])k=nt[k];
    if(b[k+1]==a[i])++k;
    if(k==lenb)w[++ans]=i-lenb+1;
}
/*数论分块*/
for(int l=1,r;l<=k;l=r+1)
{ 
    r=k/(k/l);
}
/*线性求逆元*/
inv[1]=1;
for(int i=2;i<=n;++i)inv[i]=(p-(p/i))*inv[p%i]%p;
/*
定理1:存在欧拉路的条件:图是连通的,有且只有2个奇点.
定理2:存在欧拉回路的条件:图是连通的,有0个奇点.
*/
/*Kruskal最小生成树*/
struct bian
{
    int fr,to,dis;
    friend bool operator <(const bian &a,const bian &b){return a.dis<b.dis;}
}e[100010];
int find(int x){return x==fa[x]?fa[x]:fa[x]=find(fa[x]);}
void he(int x,int y){fa[find(x)]=fa[find(y)];}
cin>>n>>m;
for(int i=1;i<=n;++i)fa[i]=i;
for(int i=1;i<=m;++i)scanf("%d%d%d",&e[i].fr,&e[i].to,&e[i].dis);
sort(e+1,e+1+m);
for(int i=1;i<=m;++i)
{
    int x=find(e[i].fr),y=find(e[i].to);
    if(x==y)continue;
    he(x,y);
    ++k;
    if(k==n-1)break;
}
/*二分图匹配*/
bool dfs(int x)
{
    for(int i=1;i<=m;++i)
        if(f[x][i]&&(!vis[i]))
        {
            vis[i]=1;
            if(!g[i]||dfs(g[i])){g[i]=x;return 1;}
        }
    return 0;   
}
cin>>n>>m>>e;
for(int i=1;i<=e;++i)
{
    scanf("%d%d",&x,&y);
    f[x][y]=1;
}
for(int i=1;i<=n;++i)
{
    memset(vis,0,sizeof(vis));
    if(dfs(i))++ans;
}
/*最长不下降子序列*/
d[1]=1;len=1;
for(int i=2;i<=n;++i)
{
    if(a[i]>=d[len])d[++len]=a[i];
    else *upper_bound(d+1,d+1+len,a[i])=a[i];
}
/*最长公共子序列*/
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<=n;++i)scanf("%d",&b[i]);
for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    if(a[i]==b[j])fp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
    else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
/*01背包*/
cin>>V>>n;
for(int i=1;i<=n;++i)scanf("%d%d",&w[i],&k[i]);
for(int i=1;i<=n;++i)
    for(int j=V;j>=w[i];--j)
    f[j]=max(f[j],f[j-w[i]]+k[i]);
cout<<f[V];
/*完全背包*/
for(int j=w[i];j<=V;j++)
/*分组背包*/
for(int i=1;i<=100;i++)
  if(t[i].size())
    {
        p=t[i].size();
        for(int j=m;j>=0;j--)
           for(int k=0;k<p;k++)
              if(j>=t[i][k].weight) dp[j]=max(dp[j],dp[j-t[i][k].weight]+t[i][k].value);
    }
/*动态开点线段树 & 线段树合并*/
void change(int &k,int l,int r,int pos,int val)
{
    if(!k)k=++cnt;
    if(l==r)
    {
        maxx[k]+=val ;wi[k]=l;
        return;
    }
    if(pos<=mid)change(lson[k],l,mid,pos,val);
    else change(rson[k],mid+1,r,pos,val);
    
    maxx[k]=max(maxx[lson[k]],maxx[rson[k]]);
    if(maxx[lson[k]]>=maxx[rson[k]])wi[k]=wi[lson[k]];
    else wi[k]=wi[rson[k]];
}
int he(int p,int q,int l,int r)
{
    if((!p)||(!q))return p+q;
    if(l==r)
    {
        maxx[p]+=maxx[q];
        return p;
    }
    lson[p]=he(lson[p],lson[q],l,mid);
    rson[p]=he(rson[p],rson[q],mid+1,r);
    
    maxx[p]=max(maxx[lson[p]],maxx[rson[p]]);
    if(maxx[lson[p]]>=maxx[rson[p]])wi[p]=wi[lson[p]];
    else wi[p]=wi[rson[p]];
    return p;
}
/*ST表*/
int ask(int l, int r) 
{
    int g = log2(r - l + 1);
    return max(a[l][g], a[r - (1 << g) + 1][g]);
}
for (int i = 1; i <= n; ++i)a[i][0] = read();
for (int j = 1; j <= 24; ++j)
    for (int i = 1; i + (1 << j) <= n + 1; ++i)
        a[i][j] = max(a[i][j - 1], a[i + (1 << (j - 1))][j - 1]);
/*ODT*/
#define IT set<node>::iterator
struct node
{
    int l,r;
    mutable int val;
    node(int L,int R=-1,int V=0):l(L),r(R),val(V){}
    friend bool operator <(const node &a,const node &b)
    {return a.l<b.l;}
}
set<node>s;
IT split(int pos)
{
    IT it=s.lower_bound(node(pos));
    if(it!=s.end()&&it->l==pos)return it;
    --it;
    int L=it->l,R=it->r;
    long long V=it->val;
    s.erase(it);
    s.insert(node{L,pos-1,V});
    return s.insert(node{pos,R,V}).first;
}
void tuiping(int l,int r,int v)
{
    IT it2=split(r+1),it1=split(l);
    s.erase(it1,it2);
    s.insert(node{l,r,v});
}
void add(int l,int r,int v)
{
    IT it2=split(r+1),it1=split(l);
    for(;it1!=it2;++it1)it1->val+=v;
}
long long ask(int l,int r,int x,int mod)
{
    IT it2=split(r+1),it1=split(l);
    long long res=0;
    for(;it1!=it2;++it1)
    res=(res+(long long)(it1->r-it1->l+1)*ksm(it1->val,(long long) (x),(long long) (mod)))%mod;
    return res;
}
/*三分*/
while(r-l>0.000001)
{
     double m1=l+(r-l)/3;
     double m2=r-(r-l)/3;
     if(check(m1)>check(m2)) r=m2;
     else l=m1;
}
/*普通Trie树*/
void Insert(int val)
{
    int t,a=0;
    for(int i=30;i>=1;--i)
    {
        t=(val&(1<<(i-1)))>>(i-1);
        if(!tr[a][t])tr[a][t]=++cnt;
        a=tr[a][t];
    }
}
int ask(int val)
{
    int t,a=0,res=0;
    for(int i=30;i>=1;--i)
    {
        t=(val&(1<<(i-1)))>>(i-1);
        if(tr[a][!t])
        {
            res+=(1<<(i-1));
            a=tr[a][!t];
        }
        else a=tr[a][t];
    }
    return res;
}
/*manacher 马拉车*/
scanf("%s", b + 1);
lenb = strlen(b + 1);
for (int i = 1; i <= lenb; ++i)a[i << 1] = b[i];
lena = lenb * 2 + 1;
for (int i = 1; i <= lena; i = i + 2)a[i] = '*';
for (int i = 1; i <= lena; ++i) 
{
    bj = 1;
    if (r < i) 
    {
        r = i; hao = i; bj = 1;
    } 
    else bj = min(r - i + 1, p[2 * hao - i]);
    while (i + bj <= lena && i - bj >= 1 && a[i + bj] == a[i - bj])bj++;
    p[i] = bj;
    if (i + bj - 1 > r) 
    {
        r = i + bj - 1; hao = i;
    }
    ans = max(ans, p[i] - 1);
}

CSP 前模板

标签:reg   二分图   输出   lower   st表   因子   else   负数   线性筛   

原文地址:https://www.cnblogs.com/wljss/p/11844396.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!