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 phone (50)
    与众不同 windows phone (49)
    重新想象 Windows 8.1 Store Apps (93)
    重新想象 Windows 8.1 Store Apps 系列文章索引
    重新想象 Windows 8.1 Store Apps (92)
    重新想象 Windows 8.1 Store Apps (91)
    重新想象 Windows 8.1 Store Apps (90)
    重新想象 Windows 8.1 Store Apps (89)
    重新想象 Windows 8.1 Store Apps (88)
    重新想象 Windows 8.1 Store Apps (87)
  • 原文地址:https://www.cnblogs.com/wljss/p/11844396.html
Copyright © 2011-2022 走看看