• NOIP2020模板


    NOIP模板

    并查集

    int find(int x)
    {
    	if(f[x]==x)
    	return f[x];
    	else 
    	return f[x]=find(f[x]);
    }
    void merge(int x,int y)
    {
    	int fx=find(x);
    	int fy=find(y);
    	if(fx!=fy)
    	f[fx]=fy;
    }
    

    快速幂

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int b,p,k;
    int qpow(int b,int p)
    {
    	int ret=1,base=b;
    	while(p>0)
    	{
    		if(p&1)
    			ret*=base;
    		ret%=k;
    		base*=base;
    		base%=k;
    		p>>=1;
    	}
    	return ret;
    }
    signed main()
    {
    	scanf("%lld%lld%lld",&b,&p,&k);
    	printf("%lld^%lld mod %lld=",b,p,k);
    	if(k==1)
    	{
    		cout << 0;
    		return 0;
    	}
    	int sr=qpow(b,p);
    	printf("%lld",sr);
    	return 0;
    }
    

    线性筛质数

    void euler(int n)
    {
    	for(int i=2;i<=n;i++)
    	{
    		if(!v[i])
    		prime[++cnt]=i;
    		for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
    		{
    			v[i*prime[j]]=1;
    			if(i%prime[j]==0)
    			break;
    		}
    	}
    }
    

    SPFA

    void spfa(int s)
    {
    	for(int i=1;i<=n;i++)
    	dis[i]=2147483647;
    	memset(inq,0,sizeof(inq));
    	queue<int> q;
    	q.push(s);
    	inq[s]=1;
    	dis[s]=0;
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		inq[x]=0;
    		for(int i=head[x];i;i=nxt[i])
    		{
    			int y=to[i];
    			int z=val[i];
    			if(dis[y]>dis[x]+z)
    			{
    				dis[y]=dis[x]+z;
    				if(!inq[y])
    				inq[y]=1,q.push(y);
    			}
    		}
    	}
    }
    

    注意:看好是否为双向边


    DIJ

    priority_queue<pair<int,int> > q;
    void dij(int s)
    {
    	memset(dis,0x3f,sizeof(dis));
    	dis[s]=0;
    	q.push(make_pair(0,s));
    	while(!q.empty())
    	{
    		int x = q.top().second;
    		q.pop();
    		if(v[x])
    		continue;
    		v[x]=1;
    		for(int i=head[x];i;i=nxt[i])
    		{
    			int y=to[i];
    			if(dis[y]>dis[x]+val[i])
    			{
    				dis[y]=dis[x]+val[i];
    				q.push(make_pair(-dis[y],y));
    			}
    		}
    	}
    }
    

    树状数组

    namespace BIT
    {
    	int tr[maxn];
    	void update(int x,int v)
    	{
    		for(int i=x;i<=n;i+=i&-i)
    		tr[i]+=v;
    	}
    	int query(int x)
    	{
    		int ret=0;
    		for(int i=x;i;i-=i&-i)
    		ret+=tr[i];
    		return ret;
    	}
    }
    

    注意查询时减一


    单调队列/滑动窗口

    for(int i=1;i<=n;i++)
    	{
    		while(l<=r&&a[i]>a[q[r]])r--;
    		q[++r]=i;
    		while(l<=r&&i-q[l]>=k)l++;
    		if(i>=k)
    		printf("%d ",a[q[l]]);
    	}
    

    Tarjan缩点

    void tarjan(int x)
    {
    	dfn[x]=low[x]=++tim;
    	s.push(x);
    	ins[x]=1;
    	for(int i=head[x];i;i=nxt[i])
    	{
    		int y=to[i];
    		if(!dfn[y])
    		{
    			tarjan(y);
    			low[x]=min(low[x],low[y]);
    		}
    		else if(ins[y])
    		low[x]=min(low[x],low[y]);
    	}
    	if(low[x]==dfn[x])
    	{
    		int cur;
    		++cnt;
    		do
    		{
    			cur=s.top();
    			s.pop();
    			ins[cur]=0;
    			scc[cur]=cnt;
    			V[cnt]+=v[cur];
    		}while(cur!=x);
    	}
    }
    

    注意重建图时点的问题


    拓扑排序

    int topo()
    {
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		for(int i=head[x];i;i=nxt[i])
    		{
    			int y=to[i];
    			dp[y]=max(dp[y],dp[x]+V[y]);
    			deg[y]--;
    			if(!deg[y])
    			q.push(y);
    		}
    	}
    	int ans=0;
    	for(int i=1;i<=n;i++)
    	ans=max(ans,dp[i]);
    	return ans;
    }
    

    线性求逆元

    for(int i=2;i<=n;i++)
    {
    	inv[i]=(ll)(p-p/i)*inv[p%i]%p;
    	printf("%d
    ",inv[i]);
    }
    

    三分法

    while(fabs(l-r)>=eps)
    	{
    		double mid=(l+r)/2;
    		if(F(mid+eps)>F(mid-eps)) l=mid;
    		else r=mid;
    	}
    

    线段树1(区间修改,区间求和)

    namespace ST
    {
    	int tr[maxn<<2];
    	int tag[maxn<<2];
    	#define lson p<<1
    	#define rson p<<1|1
    	void mark(int l,int r,int v,int p)
    	{
    		tag[p]+=v;
    		tr[p]+=(r-l+1)*v;
    	}
    	void pushdown(int l,int r,int p)
    	{
    		int mid=(l+r)>>1;
    		mark(l,mid,tag[p],lson);
    		mark(mid+1,r,tag[p],rson);
    		tag[p]=0;
    	}
    	int query(int l,int r,int x,int y,int p)
    	{
    		if(x<=l&&y>=r)
    		return tr[p];
    		int ret=0;
    		int mid=(l+r)>>1;
    		if(tag[p])
    		pushdown(l,r,p);
    		if(x<=mid) ret+=query(l,mid,x,y,lson);
    		if(y>mid) ret+=query(mid+1,r,x,y,rson);
    		return ret;
    	}
    	void update(int l,int r,int x,int y,int v,int p)
    	{
    		if(x<=l&&y>=r)
    		{
    			mark(l,r,v,p);
    			return;
    		}
    		int mid=(l+r)>>1;
    		if(tag[p])
    		pushdown(l,r,p);
    		if(x<=mid) update(l,mid,x,y,v,lson);
    		if(y>mid) update(mid+1,r,x,y,v,rson);
    		tr[p]=tr[lson]+tr[rson];
    	} 
    	void build(int l,int r,int p)
    	{
    		if(l==r)
    		{
    			scanf("%lld",&tr[p]);
    			return ;
    		}
    		int mid=(l+r)>>1;
    		build(l,mid,lson);
    		build(mid+1,r,rson);
    		tr[p]=tr[lson]+tr[rson];
    	}
    }
    

    SPFA判负环

    bool spfa()
    {
    	q.push(1);
    	inq[1]=1;
    	memset(dis,0x3f,sizeof(dis));
    	memset(inq,0,sizeof(inq));
    	memset(cnt,0,sizeof(cnt));
    	dis[1]=0;
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		inq[x]=0;
    		for(int i=head[x];i;i=nxt[i])
    		{
    			int y=to[i];
    			if(dis[y]>dis[x]+val[i])
    			{
    				dis[y]=dis[x]+val[i];
    				cnt[y]=cnt[x]+1;
    				if(cnt[y]>n+1)
    				return 1;
    				if(!inq[y])
    				q.push(y),inq[y];
    			}
    		}
    	}
    	return 0;
    }
    

    注意初始化


    单调栈

    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    		while(a[s[top]]<a[i]&&top!=0)
    		{
    			l[s[top]]=i;
    			top--;
    		}
    		s[++top]=i;
    	}
    

    差分约束

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    #define maxn 600100
    int head[maxn],nxt[maxn],to[maxn],val[maxn],tot=0;
    void add(int x,int y,int z)
    {
    	to[++tot]=y;
    	nxt[tot]=head[x];
    	val[tot]=z;
    	head[x]=tot;
    }
    int dis[maxn],inq[maxn],cnt[maxn];
    queue<int> q;
    bool spfa(int s)
    {
    	memset(dis,0x3f,sizeof(dis));
    	memset(inq,0,sizeof(inq));
    	memset(cnt,0,sizeof(cnt));
    	dis[s]=0;
    	cnt[s]=1;
    	inq[s]=1;
    	q.push(s);
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		inq[x]=0;
    		for(int i=head[x];i;i=nxt[i])
    		{
    			int y=to[i];
    			if(dis[y]>dis[x]+val[i])
    			{
    				dis[y]=dis[x]+val[i];
    				cnt[y]=cnt[x]+1;
    				if(cnt[y]>n+1)
    				return 1;
    				if(!inq[y])
    				q.push(y),inq[y]=1;	
    			}
    		}
    	}
    	return 0;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		add(y,x,z);
    	}
    	for(int i=1;i<=n;i++)
    	add(0,i,0);
    	if(!spfa(0))
    	{
    		for(int i=1;i<=n;i++)
    		printf("%d ",dis[i]);
    	}
    	else 
    	printf("NO
    ");
    	return 0;
    }
    

    注意判负环


  • 相关阅读:
    IP保留地址
    HTML5读取本地文件
    angularjs中动态为audio绑定src
    canvas移动端常用技巧图片loading
    angularjs三级联动
    angular实现select的ng-options
    ng-bind-html在ng-repeat中问题的解决办法
    JS判断是否在微信浏览器打开
    angular实现select的ng-options
    创建 AngularJS 自定义过滤器,带自定义参数
  • 原文地址:https://www.cnblogs.com/Marcelo/p/14082367.html
Copyright © 2020-2023  润新知