非精写版-51nod基础训练

Posted iuk11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非精写版-51nod基础训练相关的知识,希望对你有一定的参考价值。

第一部分地址
第二部分地址

无向图最小生成树

Kruskal算法,基于边选择的方法,适合稠密图。模板:

#include<bits/stdc++.h>
using namespace std;
const int maxn=50050;
struct node{
    int fr,to,w;
}e[maxn];
bool cmp(const node &a,const node &b){
    return a.w<b.w;
}
int father[maxn];
int find(int x){
    if(father[x]==x) return x;
    else father[x]=find(father[x]);
    return father[x];
}
void add(int a,int b){
    father[find(a)]=find(b);
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&e[i].fr,&e[i].to,&e[i].w);
    }
    sort(e+1,e+1+m,cmp);
    for(int i=1;i<=n;i++){
        father[i]=i;
    }
    int ans=0;
    for(int i=1,j=1;j<n;i++){
        if(find(e[i].fr)==find(e[i].to)) continue;
        else{
            ans+=e[i].w;
            add(e[i].fr,e[i].to);
            j++;
        }
    }
    printf("%d",ans);
	//system("pause");
    return 0;
}

Prim算法,基于点选择的方法,适合稀疏图。模板:
(本题并不太适用,但也可以AC)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
typedef long long ll;
int g[maxn][maxn];
int mst[maxn][maxn];
int lowcost[maxn];
int n,m;
int prim(int x){
    int sum=0;
    for(int i=1;i<=n;i++){
        lowcost[i]=g[x][i];
    }
    lowcost[x]=-1;
    for(int i=1;i<=n-1;i++){
        int mind=INF,minid=0;
        for(int j=1;j<=n;j++){
            if(lowcost[j]<mind&&lowcost[j]!=-1){
                mind=lowcost[j];
                minid=j;
            }
        }
        sum+=mind;
        lowcost[minid]=-1;
        for(int j=1;j<=n;j++){
            if(lowcost[j]>g[minid][j]){
                lowcost[j]=g[minid][j];
            }
        }
    }
    return sum;
}
int main(){
    scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                g[i][j]=INF;
            }
        }
        int u,v,w;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&w);
            g[u][v]=g[v][u]=w;
        }
        int sum=prim(1);
        printf("%d\\n",sum);
	//system("pause");
    return 0;
}

威佐夫游戏V2

考虑精度问题的威佐夫游戏。
我们在前文中知道:
第 一 个 值 = 差 值 ∗ ( s q r t ( 5 ) + 1 ) / 2 第一个值 = 差值 *(sqrt(5)+1)/2 =(sqrt(5)+1)/2
( s q r t ( 5 ) + 1 ) / 2 (sqrt(5)+1)/2 (sqrt(5)+1)/2在保留精度时保留不到27位小数,那最后算出来的值因为精度原因造成与n不相等,发生错误。
应手动模拟大数乘法,把18位拆成两个9位储存。
模拟两位数乘以三位数的手写运算。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m;
ll tmp[3]={618033988,749894848,204586834};
ll mod=1000000000;
int main(){
	int t;
	cin>>t;
	while(t--){
		cin>>m>>n;
		if(m<n) swap(n,m);
		ll c=m-n;
		ll ta=c/mod,tb=c%mod;
		ll tp=tb*tmp[2];
		tp=ta*tmp[2]+tb*tmp[1]+tp/mod;
		tp=ta*tmp[1]+tb*tmp[0]+tp/mod;
		tp=c+ta*tmp[0]+tp/mod;
		if(tp==n) cout<<"B"<<endl;
		else cout<<"A"<<endl;
	}
	//system("pause");
	return 0;
}

已经开始不按照顺序写题解了。
既希望快点完成整个零级题目,又怕囫囵吞枣,知识都是一知半解。


乘法逆元

参考文章1
参考文章2
题目要求: k ∗ m % n = 1 k*m\\%n=1 km%n=1,求k的最小正值。
根据公式推导 a ∗ x % n = 1 % n , a = m , x = k a*x\\%n=1\\%n,a=m,x=k ax%n=1%na=m,x=k我们要求的k就是最小正数解x的值。 a ∗ x + b ∗ y = 1 , b = n a*x+b*y=1,b=n ax+by=1b=n意思为在模n相等的情况下,其实就是相差了y个n。
最终根据扩展欧几里得求出x的值,由于我们需要正整数的解,如果是负数还需要再进一步处理: x = ( x % n + n ) % n x=(x\\%n+n)\\%n x=(x%n+n)%n
证明完毕。
后面还有一些知识点:

  • 求逆元用扩展欧几里得
  • 若模数是质数可以直接用费马小定理,若不是质数用欧拉函数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int exgcd(int a,int b,int &x,int &y){
	int d=a;
	if(b!=0){
		d=exgcd(b,a%b,y,x);
		y-=(a/b)*x;
	}else{
		x=1,y=0;
	}
	return d;
}
int moi(int a,int m){
	int x,y;
	exgcd(a,m,x,y);
	return (m+x%m)%m;
}
int main(){
	int n,m;
	cin>>n>>m;
	cout<<moi(n,m)<<endl;
	//system("pause");
	return 0;
}

斐波那契数列的第N项(矩阵快速幂)

[ f ( n ) f ( n − 1 ) ] = [ 1 1 1 0 ] [ f ( n − 1 ) f ( n − 2 ) ] \\left[ \\begin{matrix} f(n) \\\\ f(n-1) \\\\ \\end{matrix} \\right] = \\left[ \\begin{matrix} 1 & 1 \\\\ 1 & 0 \\\\ \\end{matrix} \\right] \\left[ \\begin{matrix} f(n-1) \\\\ f(n-2) \\\\ \\end{matrix} \\right] [f(n)f(n1)]=[1110][f(n1)f(n2)] [ f ( n ) f ( n − 1 ) ] = [ 1 1 1 0 ] [ 1 1 1 0 ] [ f ( n − 2 ) f ( n − 3 ) ] \\left[ \\begin{matrix} f(n) \\\\ f(n-1) \\\\ \\end{matrix} \\right] = \\left[ \\begin{matrix} 1 & 1 \\\\ 1 & 0 \\\\ \\end{matrix} \\right] \\left[ \\begin{matrix} 1 & 1 \\\\ 1 & 0 \\\\ \\end{matrix} \\right] \\left[ \\begin{matrix} f(n-2) \\\\ f(n-3) \\\\ \\end{matrix} \\right] [f(n)f(n1)]=[1110][1110][f(n2)f(n3)] [ f ( n ) f ( n − 1 ) ] = [ 1 1 1 0 ] n − 1 [ f ( 2 ) f ( 1 ) ] \\left[ \\begin{matrix} f(n) \\\\ f(n-1) \\\\ \\end{matrix} \\right] = \\left[ \\begin{matrix} 1 & 1 \\\\ 1 & 0 \\\\ \\end{matrix} \\right] ^{n-1} \\left[ \\begin{matrix} f(2) \\\\ f(1) \\\\ \\end{matrix} \\right] 非精写版-51nod基础训练

非精写版-51nod基础训练

非精写版-51nod基础训练(终)

非精写版-51nod基础训练(持续更新)

51nod_1459 最短路 dijkstra 特调参数

1057 N的阶乘(51NOD基础题)