zoukankan      html  css  js  c++  java
  • CSP 前模板

    快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);
    }
    
  • 相关阅读:
    【代码沉淀】
    【整理总结】目录
    Windows service installer with InstallShield LE
    (The application/json Media Type for JavaScript Object Notation (JSON))RFC4627-JSON格式定义
    Microsoft .NET Framework 4 安装 1603错误的解决
    SQL SERVER 无法正常连接的那些事
    【整理总结】我的装机软件以及说明
    Wcf服务测试自带工具
    Postgresql 远程连接配置
    Caliburn.Micro
  • 原文地址:https://www.cnblogs.com/wljss/p/11844396.html
Copyright © 2011-2022 走看看