zoukankan      html  css  js  c++  java
  • 「csp模拟」模拟测试1

    • 分很低呀,暴力分打的不足,别人的T1暴力70+,我只有50。 T3的部分分也没有拿够,还有有几种比较简单的情况没有考虑到。
    • 图论的题目总是想不到暴力,或者是想到了暴力总有细节出问题,以后注意吧。

    平凡的函数

    题目描述

    题解

    直接线性筛即可, 然后记录一下质因子的幂数。

    code

    #include <cstdio>
    #include <cctype>
    #include <cmath>
    #include <iostream>
    using namespace std;
    #define print(x) cerr << #x << " : " << x << endl;
    inline int read() {
        int k = 0, f = 1; char ch = getchar();
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
        for(; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
        return k * f;
    }
    const int maxn = 5e7 + 100;
    int prime[maxn], vis[maxn], f[maxn];
    signed main() {
    #ifdef local
        freopen("in", "r", stdin);
    #else
        freopen("func.in", "r", stdin);
        freopen("func.out", "w", stdout);
    #endif
        int n = read(), cnt = 0;
        long long ans = 1;
        f[1] = 1;
        for (int i = 2; i <= n; i++) {
            if (!vis[i]) prime[++cnt] = i, f[i] = i ^ 1;
            for (int j = 1; i * prime[j] <= n; j++) {
                vis[i * prime[j]] = 1;
                if (i % prime[j] == 0) {
                    int x = i, m = 1;
                    while (x % prime[j] == 0) x /= prime[j], ++m;
                    f[i * prime[j]] = f[x] * (prime[j] ^ m);
                    break;
                }
                f[i * prime[j]] = f[i] * f[prime[j]];
            }
            ans += f[i];
        }
        printf("%lld
    ", ans);
        return 0;
    }
    

    那一天她离我而去

    题目描述

    她走的悄无声息,消失的无影无踪。
    至今我还记得那一段时间,我们一起旅游,一起游遍山水。到了最终的景点,她却悄无声息地消失了,只剩我孤身而返。
    现在我还记得,那个旅游区可以表示为一张由n个节点m条边组成无向图。我故地重游,却发现自己只想尽快地结束这次旅游。我从景区的出发点(即 1 号节点)出发,却只想找出最短的一条回路重新回到出发点,并且中途不重复经过任意一条边。
    即:我想找出从出发点到出发点的小环。

    题解

    • 暴力思路:将所有与起点相连的边删除,从这些相连的点跑到其他相连点的最短路尝试更新答案
    • 正解思路:对暴力进行优化,分组进行最短路, 因为任意两个不同的点,二进制一定至少存在一位不同,我们以每个二进制位的0,1进行分组,每组点组成的环一定被至少一次更新,于是可以达到目的, 复杂度 (O(m log^2n))

    code

    暴力
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e4 + 5, maxm = 4e4 + 5;
    const int Inf = 0x3f3f3f3f;
    struct node { int to, next, dis; } e[maxm<<1];
    int head[maxn], ecnt;
    void add(int a,int b,int c){ e[ecnt] = (node){b, head[a], c}; head[a] = ecnt++; }
    int vis[maxn], dis[maxn];
    void Spfa(int x){
        memset(dis,0x3f,sizeof(dis));    
        memset(vis,0,sizeof(vis));
        queue<int> q;
        q.push(x); dis[x]=0;
        while(!q.empty()){
            int u = q.front(); q.pop();
            vis[u] = 0;
            for(int i = head[u]; ~i; i=e[i].next){
                int v = e[i].to, d;
                if(dis[v] > (d = dis[u] + e[i].dis)) {
                    dis[v] = dis[u] + e[i].dis;
                    if(!vis[v]) q.push(v), vis[v] = 1;
                }
            }
        } 
    }
    int main(){
    #ifndef debug
        freopen("leave.in", "r", stdin);
        freopen("leave.out", "w", stdout);
    #endif
        int T; scanf("%d",&T);
        while(T--){
            int n, m; scanf("%d%d", &n, &m);
            memset(head, -1, sizeof(head));
            ecnt = 0;
            for(int i = 1; i <= m; i++){
                int u, v, dis; scanf("%d%d%d", &u, &v, &dis);
                add(u, v, dis), add(v, u, dis);
            }
            int ans = Inf;
            for(int i = head[1]; ~i; i = e[i].next) {
                int temp = e[i].dis;
                e[i].dis = e[i ^ 1].dis = Inf;
                Spfa(1);
                ans = std::min(ans, dis[e[i].to] + temp);
                e[i].dis = e[i ^ 1].dis = temp;
            }
            if(ans == Inf) printf("-1
    ");
            else printf("%d
    ", ans);
        }
    }
    
    
    正解
    #include <bits/stdc++.h>
    using namespace std;
    #define print(x) cerr << #x << " : " << x << endl;
    inline int read() {
        int k = 0, f = 1; char ch = getchar();
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
        for(; isdigit(ch); ch = getchar()) k = k * 10 + ch - '0';
        return k * f;
    }
    const int maxn = 3e4 + 100;
    struct node { int to, next, dis; } e[maxn * 8];
    struct edge { int to, dis; } g[maxn * 8];
    int head[maxn], ecnt = 0;
    inline void add(int u, int v, int d) { e[++ecnt] = (node) {v, head[u], d}; head[u] = ecnt; }
    int dis[maxn], vis[maxn];
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
    inline void dijkstra(int s) {
        memset(vis, 0, sizeof(vis)), memset(dis, 0x3f, sizeof(dis));
        dis[s] = 0;
        q.push(make_pair(0, s));
        while (q.size()) {
            int x = q.top().second;
            q.pop();
            if (vis[x]) continue;
            for (register int i = head[x]; i; i = e[i].next) {
                int y = e[i].to, d;
                if (dis[y] > (d = dis[x] + e[i].dis)) {
                    dis[y] = d;
                    q.push(make_pair(dis[y], y));
                }
            }
        }
    }
    int main() {
    #ifndef debug
        freopen("leave.in", "r", stdin);
        freopen("leave.out", "w", stdout);
    #endif
        int T = read();
        while(T--) {
            int n = read(), m = read();
            memset(head, 0, sizeof(head));
            ecnt = 1;
            int ans = 0x3f3f3f3f;
            int gcnt = 0;
            for (register int i = 1; i <= m; i++) {
                int x = read(), y = read(), z = read();
                if(x > y) swap(x, y);
                if(x == 1) g[++gcnt] = (edge){y, z};
                else add(x, y, z), add(y, x, z);
            }
            int tot = n;
            for(int i = 1; i <= n; i <<= 1) {
                int s = ++tot, t = ++tot;
                for(int j = 1; j <= gcnt; j++) {
                    if(g[j].to & i) add(s, g[j].to, g[j].dis);
                    else add(g[j].to, t, g[j].dis);
                } 
                dijkstra(s);
                ans = min(ans, dis[t]);
            }
            if (ans == 0x3f3f3f3f) printf("-1
    ");
            else printf("%d
    ", ans);
        }
        return 0;
    }
    

    熟练剖分(tree)

    题目描述


    题解

    • 复制一份标准题解
      容易发现总方案数为所有节点的儿子个数的乘积。
      可以计算每个时间代价的方案数是多少,最后算出总答案,除掉总方案数就是期望。
      这个东西可以通过 dp 来计算,设 (dp_{i,j}) 表示节点 (i) 子树中最坏时间代价为 (j) 的方案数。
      在归并子树的过程中,给 dp 数组多加一维,表示是否已经选择过重儿子即可。

    coding ...

  • 相关阅读:
    网络安全协议(1)
    CG-CTF(6)
    CG-CTF(5)
    CG-CTF(4)
    CG-CTF(3)
    MAC地址欺骗(原理及实验)
    CG-CTF(2)
    CG-CTF(1)
    【转载】Spring Boot【快速入门】2019.05.19
    【编程大系】Java资源汇总
  • 原文地址:https://www.cnblogs.com/hellohhy/p/13728231.html
Copyright © 2011-2022 走看看