• Noip2018 考前准备


    未完成先看吧.大概9.1号完成.
    然而现在都8102年了...

    基础算法

    二分

    求最小值最大.
    跳石头

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int maxN = 50000 + 7;
    
    int a[maxN],n,m;
    int L;
    
    inline int read() {
        register int x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
        return x * f;
    }
    
    bool calc(int k) {
        int num = 0,path = 0;
        for(int i = 1;i <= n;++ i) {
            if(a[i] - a[path] < k) { 
                num ++;
            }else path = i;
        }
        return num <= m;
    }
    
    int main() {
        L = read();n = read();m = read();
        for(int i = 1;i <= n;++ i) a[i] = read();
        n ++;
        a[n] = L;
        int l = 0,r = L,ans;
        while(l <= r) {
            int mid = (l + r) >> 1;
            if(calc(mid)) {
                ans = mid;
                l = mid + 1;
            }
            else r = mid - 1;
        }
        printf("%d",ans);
        return 0;
    }
    

    模拟(未补)

    高精(未学习)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<string>
    using namespace std;
    
    
    
    struct bignum
    {
        int n;
        int a[500];
        bignum()
        {
            n = 0;
            memset(a, 0, sizeof(a));
        }
            
        bignum(string s)
        {
            n = s.size();
            memset(a, 0, sizeof(a));
            for (int i = 0; i < n; i++)
                a[i] = s[n - 1 -i] -'0';
        }
        bignum(int s)
        {
            memset(a, 0, sizeof(a));
            n = 0;
            while (s > 0)
            {
                a[n] = s % 10;
                s /= 10;
                n++;
            }
        }
        void work()
        {
            for (int i = 0; i < n; i++)
            {
                if (a[i] < 0)
                {
                    int tmp = (-a[i] - 1) / 10 + 1;
                    a[i] += 10 * tmp;
                    a[i + 1] -= tmp;
                }
                if (a[i] >= 10)
                {
                    int tmp = a[i] / 10;
                    a[i] -= 10* tmp;
                    a[i + 1] += tmp;
                    if (i == n - 1 && a[i + 1] > 0) n++;
                }
            }
            while (n > 0 && a[n - 1] == 0) n--;
        }
        void print()
        {
            for (int i = n - 1; i >= 0; i--)
                cout << a[i];
            cout << endl;
        }
    };
    
    bignum operator + (const bignum &a, const bignum &b)
    {
        bignum c;
        c.n = max(a.n, b.n);
        for (int i = 0; i < c.n; i++)
            c.a[i] = a.a[i] + b.a[i];
        c.work();
        return c;
    }
    
    
    bignum operator - (const bignum &a, const bignum &b)
    {
        bignum c;
        c.n = max(a.n, b.n);
        for (int i = 0; i < c.n; i++)
            c.a[i] = a.a[i] - b.a[i];
        c.work();
        return c;
    }
    
    
    bignum operator * (const bignum &a, const bignum &b)
    {
        bignum c;
        c.n = a.n + b.n - 1;
        for (int i = 0; i < a.n; i++)
            for (int j = 0; j < b.n; j++)
                c.a[i + j] += a.a[i] * b.a[j];
        c.work();
        return c;
    }
    
    
    int main()
    {
        string s;
        cin >> s;
        int x;
        cin >> x;
        bignum a(s);
        bignum b(x);
        (a + b).print();
        (a - b).print();
        (a * b).print();
        return 0;
    }
    

    搜索(未补)

    排序

    merge_sort(归并排序)

    #include <iostream>
    #include <cstdio>
    const int maxN = 100000 + 7;
    
    int z[maxN],a[maxN];
    
    inline int read() {
    	int x = 0,f = 1;char c = getchar();
    	while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
    	return x * f;
    }
    
    void merge(int l,int r) {
    	if(l == r) return;
    	int mid = l + r >> 1;
    	merge(l,mid);
    	merge(mid + 1,r);
    	int z1 = l,z2 = mid + 1;
    	for(int i = l;i <= r;++ i) {
    		if(z1 <= mid) 
    			if(z2 <= r) 
    				if(a[z1] >= a[z2]) z[i] = a[z2 ++];
    				else z[i] = a[z1 ++];
    			else z[i] = a[z1 ++];
    		else z[i] = a[z2 ++];
    	}
    	for(int i = l;i <= r;++ i) 
    		a[i] = z[i];
    }
     
    int main() {
    	int n = read();
    	for(int i = 1;i <= n;++ i) 
    		a[i] = read();
    	merge(1,n);
    	for(int i = 1;i <= n;++ i) 
    		printf("%d ",a[i]);
    	return 0;
    }
    

    图论

    树的直径

    POJ2631

    #include <cstring>
    #include <iostream>
    #include <cstdio>
    #include <vector>
    const int maxN = 10000 + 7;
    using namespace std;
    
    int ans,id,n = 1;
    int Rode[maxN];
    
    struct Node{
    	int v,w;
    };
    
    vector<Node>Q[maxN];
    
    void dfs1(int now,int fa) {
    	for(int i = 0;i < Q[now].size();++ i) {
    		int v = Q[now][i].v,w = Q[now][i].w;
    		if(v == fa) continue;
    		Rode[v] = Rode[now] + w;
    		dfs1(v,now);
    	}
    	return;
    }
    
    int max(int a,int b) {
    	return a > b ? a : b ;
    }
    
    int main() {
    	#ifdef WIN32
        freopen("a.txt","r",stdin);
        #endif
    	int u,v,w;
    	while(scanf("%d%d%d",&u,&v,&w) == 3) {
    		Q[u].push_back((Node) {v,w});
    		Q[v].push_back((Node) {u,w});
    		n ++;
    	}
    	dfs1(1,-1);
    	for(int i = 1;i <= n;++ i) {		
    		if(ans < Rode[i]) {
    			ans = Rode[i];
    			id = i;
    		}
    	}
    	memset(Rode,0,sizeof(Rode)); 
    	dfs1(id,-1);
    	ans = 0;
    	for(int i = 1;i <= n;++ i)
    		ans = max(ans,Rode[i]);
    	printf("%d",ans);
    	return 0;
    }
    

    树的重心

    POJ1655

    #include <iostream>
    #include <cstdio>
    #include <vector> 
    const int maxN = 20000 + 7;
    using namespace std;
     
    vector<int> g[maxN];
    int n;
    int ans,id;
    
    int max(int a,int b) {return a > b ? a : b;}
    int min(int a,int b) {return a > b ? b : a;}
    
    int dfs(int now,int fa) {
    	int son = 1,maxson = 0,kkk;
    	for(int i = 0;i < g[now].size();++ i) {
    		int v = g[now][i];
    		if(v == fa) continue;
    		int Q = dfs(v,now);
    		son += Q;
    		maxson = max(maxson,Q);
    	}
    	kkk = max(maxson,n - son);
    	if(kkk < ans) {
    		ans = kkk;
    		id = now;
    	}
    	return son;
    }
    
    int main() {
    	int T;
    	scanf("%d",&T);
    	while(T --) {
    		scanf("%d",&n);
    		for(int i = 1;i <= n;++ i) 
    			g[i].clear(); 
    		for(int i = 1,u,v;i < n;++ i) {
    			scanf("%d%d",&u,&v);
    			g[u].push_back(v);
    			g[v].push_back(u);
    		}
    		ans = 0x7fffffff;
    		dfs(1,-1);
    		printf("%d %d
    ",id,ans);
    	} 
    	return 0;
    }
    

    最短路算法

    题目单源最短路径(弱化版)

    Spfa

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    const int maxN = 100000 + 7;
    const int maxM = 200000 + 7;
    const int inf = 2147483647;
    using namespace std;
    
    int dis[maxN];
    bool vis[maxN];
    int max(int a,int b) {return a > b ? a : b;}
    int min(int a,int b) {return a > b ? b : a;}
    
    struct Node{
    	int v,w,nex;
    }Map[maxM];
    
    int head[maxN],num;
    
    void add_Node(int u,int v,int w) {
    	Map[++ num].v = v;
    	Map[num].w = w;
    	Map[num].nex = head[u];
    	head[u] = num;
    	return;
    }
    
    void spfa(int now) {
    	queue<int>q;
    	q.push(now);
    	vis[now] = true;
    	dis[now] = 0;
    	while(!q.empty()) {
    		int u = q.front();q.pop();
    		vis[u] = 0; 
    		for(int i = head[u];i != -1;i = Map[i].nex) {
    			int v = Map[i].v;
    			if(dis[v] > dis[u] + Map[i].w) {
    				dis[v] = dis[u] + Map[i].w;
    				if( !vis[v] ) {
    					vis[v] = true;
    					q.push(v);
    				}
    			}
    		}
    	}
    	return ;
    }
    
    int main() {
    	memset(dis,0x3f,sizeof(dis));
    	memset(head,-1,sizeof(head));
    	int n,m,s;
    	scanf("%d%d%d",&n,&m,&s);
    	for(int i = 1,u,v,w;i <= m;++ i) {
    		scanf("%d%d%d",&u,&v,&w);
    		add_Node(u,v,w);
    	}
    	spfa(s);
    	for(int i = 1;i <= n;++ i) 
    		printf("%d ",dis[i] == 0x3f3f3f3f ? inf : dis[i]);
    	return 0;
    }
    

    Dijkstra

    #include <iostream>
    #include <cstdio>
    #include <queue>
    using namespace std;
    const int inf = 0x7fffffff;
    const int maxN = 100000 + 7;
    const int maxM = 200000 + 7;
    
    struct Node{
    	int x,y;
    	inline bool operator < (const Node &a) const {
    		return y > a.y;
    	}
    }; 
    priority_queue<Node> q;
    struct qode{
    	int v,nex,w;
    }Map[maxM];
    
    int s,dis[maxN],n,m,num,head[maxN];
    
    void add_Node(int u,int v,int w) {
    	Map[++ num].v = v;
    	Map[num].w = w;
    	Map[num].nex = head[u];
    	head[u] = num; 
    }
    
    void dij() {
    	for(int i = 1;i <= n;++ i) dis[i] = inf;
    	q.push((Node){s,0});
    	dis[s] = 0;
    	while(!q.empty()) {
    		Node x = q.top();q.pop();
    		if(x.y != dis[x.x]) continue;
    		for(int i = head[x.x];i;i = Map[i].nex) {
    			int v = Map[i].v;
    			if(dis[v] > dis[x.x] + Map[i].w) {
    				dis[v] = dis[x.x] + Map[i].w;
    				q.push((Node){v,dis[v]});
    			}
    		}
    	} 
    	for(int i = 1;i <= n;++  i) {
    		printf("%d ",dis[i]);
    	}
    }
    
    int main() {
    	scanf("%d%d%d",&n,&m,&s);
    	for(int i = 1,u,v,w;i <= m;++ i) {
    		scanf("%d%d%d",&u,&v,&w);
    		add_Node(u,v,w);
    	}	
    	dij();
    	return 0;
    }
    

    Floyd

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int a[101][101];
    int main()  {
        int n,m,s;
        scanf("%d%d%d",&n,&m,&s);
        memset(a,0x3f,sizeof(a));
        for(int i = 1,u,v,w;i <= m;++ i) {
            scanf("%d%d%d",&u,&v,&w);
            a[u][v]=min(a[u][v],w);
        }
        for(int k = 1;k <= n;++ k) 
        	for(int i = 1;i <= n;++ i)
        		for(int j = 1;j <= n;++ j) 
        			a[i][j] = min(a[i][j],a[i][k] + a[k][j]);
        a[s][s] = 0;
        for(int i = 1;i <= n;++ i) {
            printf("%d ",a[s][i] == 0x3f3f3f3f ? 2147483647 : a[s][i]);
        }
    }
    

    最小生成树

    kruskal

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int maxN = 5000 + 7;
    const int maxM = 200000 + 7;
    
    inline int read() {
        int x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
        return x * f;
    }
    struct Node {
        int u,v,w;
    }Q[maxM];
    int fa[maxN];
    
    int find(int x) {
        return fa[x] == x ? x : fa[x] = find(fa[x]);
    }
    
    void un(int a,int b) {
        int faa = find(a),fab = find(b);
        fa[faa] = fab;
        return;
    }
    
    bool cmp(Node a,Node b) {
        return a.w < b.w;
    }
    
    int num = 0;
    void add_Node(int u,int v,int w) {
        Q[++ num].u = u;
        Q[num].v = v;
        Q[num].w = w;
    }
    
    int main() {
        int n,m;
        n = read();m = read();
        for(int i = 1;i <= n;++ i) fa[i] = i;
        for(int i = 1,u,v,w;i <= m;++ i) {
            u = read();v = read();w = read();
            add_Node(u,v,w);
        }
        sort(Q + 1,Q + m + 1,cmp);
        int sum = 0,k = 0;
        for(int i = 1;i <= m;++ i) {
            int fau = find(Q[i].u),fav = find( Q[i].v);
            if(fau != fav) {
                k ++ ;
                sum += Q[i].w;
                un(fau,fav);
                if(k == n - 1) break;
            }
        }
        if(k == n - 1) printf("%d",sum);
        else printf("orz");
    }
    

    数论

    线性筛

    线性筛素数

    void init1(int n) {
    	vis[1] = 1;
    	for(int i = 2;i <= n;++ i) {
    		if(!vis[i]) prime[++ num] = i;
    		for(int j = 1;prime[j] * i <= n;++ j) {
    			vis[i * prime[j]] = true;
    			if(i % prime[j] == 0) break;
    		}
    	}
    } 
    

    线性筛phi

    int phi[maxN];
    void init2(int n) {
    	vis[1] = 1;
    	phi[1] = 1;
    	for(int i = 2;i <= n;++ i) {
    		if( !vis[i] ) {
    			prime[++ num] = i;
    			phi[i] = i - 1;
    		}
    		for(int j = 1;j <= num && prime[j] * i <= n;++ j) {
    			vis[i * prime[j]] = true;
    			if(i % prime[j] == 0) {
    				phi[i * prime[j]] = phi[i] * prime[j];
    				break;
    			}
    			phi[i * prime[j]] =  phi[i] *( prime[j] - 1);
    		}
    	}	
    }
    

    线性筛莫比乌斯函数

    int mu[maxN];
    void init3(int n) {
    	vis[1] = 1;
    	mu[1] = 1;
    	for(int i = 2;i <= n;++ i) {
    		if(!vis[i]) {
    			prime[++ num] = i;
    			mu[i] = -1;
    		}
    		for(int j = 1;j <= num && prime[j] * i <= n;++ j) {
    			vis[i * prime[j]] = true;
    			if(i % prime[j] == 0) {
    				mu[i * prime[j]] = 0;
    				break;
    			}
    			mu[i * prime[j]] = -mu[i];
    		}
    	}
    	return;
    } 
    

    gcd(最大公因数)

    int gcd(int a,int b) {
    	while(b ^= a ^= b ^= a %= b);
    	return a;
    }
    

    lcm(最小公倍数)

    int lcm(int a,int b) {
    	return a / gcd(a,b) * b;
    }
    

    快速幂

    int fast_pow(int a,int b,int k) {
    	int ans = 1;
    	for(int now = a;b;b >>= 1,now = now * now) {
    		now %= k;
    		if(b & 1) ans *= now;
    		ans %= k;
    	}
    	return ans % k;
    }
    

    扩展欧几里得算法

    void exgcd(int a,int b,int &x,int &y) {
    	if( !b ) {
    		x = 1;
    		y = 0;
    		return;
    	}
    	exgcd(b,a % b,x,y);
    	int tmp = x;
    	x = y;
    	y = tmp - (a / b) * y;
    	return;
    }
    

    逆元

    nt inv(int n,int p) {
    	for(int i = 1,x,y;i <= n;++ i) {
    		exgcd(i,p,x,y);
    		printf("%d
    ",(x % p + p) % p);
    	}
    } //a * x ≡ q (mod p)
    

    矩阵快速幂

    
    ll n,m,k;
    struct Marix{
    	ll s[107][107];
    	void clear() {
    		memset(s,0,sizeof(s));
    		return;
    	}
    }ans,now,a;
    
    Marix work(Marix a,Marix b) {
    	Marix c;
    	c.clear();
    	for(ll i = 1;i <= n;++ i) 
    		for(ll j = 1;j <= n;++ j) 
    			for(ll k = 1;k <= n;++ k) 
    				c.s[i][j] = ( c.s[i][j]  % mod+ ( a.s[i][k] * b.s[k][j] ) % mod ) % mod;
    	return c;
    }
    
    void fast_pow() {
    	ans.clear();
    	for(ll i = 1;i <= n;++ i) {
    		ans.s[i][i] = 1;
    	}
    	for(now = a;k;k >>= 1,now = work(now,now)) {
    		if(k & 1) ans = work(ans,now);
    	}
    	for(ll i = 1;i <= n;++ i) {
    		for(ll j = 1;j <= n;++ j) {
    			printf("%lld ",ans.s[i][j]);
    		}
    		puts("");
    	}
    }
    void Marix_fast_power() {
    	scanf("%lld%lld",&n,&k);
    	for(int i = 1;i <= n;++ i) {
    		for(int j = 1;j <= n;++ j) {
    			scanf("%lld",&a.s[i][j]);
    		}
    	}
    	fast_pow();
    	return ;
    }
    

    数据结构

    ST表

    #include <iostream>
    #include <cstdio>
    #define max(a,b) a > b ? a : b
    #define min(a,b) a > b ? b : a
    const int maxN = 1e5 + 7; 
    using namespace std;
    int f[maxN][21];
    int a[maxN];
    int bin[maxN];
    int n,m;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    
    void build_st() {
    	for(int i = 1;(1 << i) <= n;++ i) 
    		bin[(1 << i)] = i;
    	for(int i = 3;i <= n;++ i)
    		if(!bin[i]) bin[i] = bin[i - 1];
    	for(int i = 1;i <= n;++ i) 
    		f[i][0] = a[i];
    	for(int j = 1;(1 << j) <= n;++ j) {
    		for(int i = 1;i + (1 << j) - 1 <= n;++ i) {
    			f[i][j] = max(f[i + (1 << (j - 1))][j - 1],f[i][j - 1]);
    		} 
    	}
    }
    
    int query(int l,int r) {
    	int x = bin[r - l + 1];
    	return max(f[l][x],f[r - (1 << x) + 1][x]); 
    }
    int main() {
    	n = read();m = read();
    	for(int i = 1;i <= n;++ i) 
    		a[i] = read();
    	build_st();
    	int l,r;
    	while(m --) {
    		l = read();r = read();
    		printf("%d
    ",query(l,r));
    	}	
    	return 0;
    }
    

    并查集

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int maxN = 10000 + 7;
    
    int fa[maxN];
    
    inline int read() {
    	int x = 0,f = 1;char c = getchar();
    	while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
    	return x * f;
    }
    
    int find(int x) {
    	return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
    }
    
    void unit(int u,int v) {
    	int fau = find(u),fav = find(v);
    	fa[fau] = fav;
    	return;
    }
    
    int main() {
    	int n,m;
    	n = read();m = read();
    	for(int i = 1;i <= 10000;++ i) 
    		fa[i] = i;
    	int opt,u,v;
    	while(m -- ) {
    		opt = read();u = read();v = read();
    		if(opt & 1) unit(u,v);
    		else {
    			int fau = find(u),fav = find(v);
    			if(fau == fav) printf("Y
    ");
    			else printf("N
    ");
    		}
    	}
    }
    
  • 相关阅读:
    软工实践寒假作业(1/2)
    javaSprintBoot技术总结
    个人作业——软件工程实践总结&个人技术博客
    个人作业软件评测
    结对第二次作业——某次疫情统计可视化的实现
    结对第一次—疫情统计可视化(原型设计)
    软工实践寒假作业(2/2)
    《软件工程》_寒假作业1_职业生涯规划
    部署前端项目和后端项目到服务器
    软件工程实践总结&个人技术博客
  • 原文地址:https://www.cnblogs.com/tpgzy/p/9451825.html
Copyright © 2020-2023  润新知