zoukankan      html  css  js  c++  java
  • 《2018 Multi-University Training Contest 7》

    Age of Moyu:

    这个题只要看到隐藏的一个线索就可以做了。

    因为这里的权值都是1,如果当前有一种方案最短路大于原先的,但是可以增加一种新颜色,这样也不需要加入,因为我们到了u点后,到后面都是需要变成他的后继边里的某一边且只需要花费1的代价。

    所以对于大于的方案就可以省去。

    但是可能存在多个最短路距离一样颜色不用的情况,所以我们可以用set记录每个点最短距离包含的颜色数,来更行。

    这里用spfa来更快,因为标记一下,如果在队列里没更新到,那么因为我们已经插入到set里了,就不需要再放入队列了。

    这题还有好多玄学问题。。两个初始化位置从1开始就超时,一定要从0开始。而且快读被卡掉了。。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,set<int>> pii;
    const int N = 1e5 + 5;
    const int M = 1e5 + 5;
    const LL Mod = 199999;
    #define pi acos(-1)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL 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<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    
    int n,m;
    typedef pair<int,int> pt;
    struct Node{int to,col;};
    vector<Node> G[N];
    pii dis[N];
    bool vis[N];
    void solve() {
        queue<int> Q;
        for(int i = 0;i <= n;++i) dis[i].first = INF,dis[i].second.clear();
        dis[1].first = 0;
        Q.push(1);
        while(!Q.empty()) {
            int u = Q.front();
            Q.pop();
            vis[u] = 0;
            for(auto v : G[u]) {
                int cost = (dis[u].second.find(v.col) == dis[u].second.end());
                if(dis[v.to].first > dis[u].first + cost) {
                    dis[v.to].first = dis[u].first + cost;
                    dis[v.to].second.clear();
                    dis[v.to].second.insert(v.col);
                    if(vis[v.to] == 0) {
                        vis[v.to] = 1;
                        Q.push(v.to);
                    }
                }
                else if(dis[v.to].first == dis[u].first + cost && (dis[v.to].second.find(v.col) == dis[v.to].second.end())) {
                    dis[v.to].second.insert(v.col);
                    if(vis[v.to] == 0) {
                        vis[v.to] = 1;
                        Q.push(v.to);
                    }
                }
            }
    
        }
    }
    int main() {
        while(~scanf("%d %d",&n,&m)) {
            for(int i = 0;i <= n;++i) G[i].clear();
            while(m--) {
                int x,y,z;scanf("%d %d %d",&x,&y,&z);
                G[x].push_back(Node{y,z});
                G[y].push_back(Node{x,z});
            }
            solve();
            printf("%d
    ",dis[n].first == INF ? -1 : dis[n].first);
        }
    
       // system("pause");
        return 0;
    }
    View Code

    Sequence:

    这题真的想到了做法,但是一开始觉得不太可能这样做。(为什么不相信自己,去尝试一下呢。。

    首先这里很明显是矩阵快速幂,但是这个向下取整的东西不好搞。

    但是又可以想到,我们可以整除分块去求他。

    然后就在整除分块里跑矩阵快速幂就行了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,set<int>> pii;
    const int N = 1e6 + 5;
    const int M = 1e5 + 5;
    const LL Mod = 1e9 + 7;
    #define pi acos(-1)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        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<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
    }
    using namespace FASTIO;
    
    LL ADD(LL a,LL b) {return (a + b) % Mod;}
    struct Mat{
        LL m[5][5];
        Mat operator * (Mat &a)const{
            Mat c;memset(c.m,0,sizeof(c.m));
            for(int i = 1;i <= 3;++i) {
                for(int j = 1;j <= 3;++j) {
                    for(int k = 1;k <= 3;++k) {
                        c.m[i][j] = ADD(c.m[i][j],m[i][k] * a.m[k][j] % Mod);
                    }
                }
            }
            return c;
        }
    };
    
    Mat quick_mi(Mat a,LL b) {
        Mat res;memset(res.m,0,sizeof(res.m));
        for(int i = 1;i <= 3;++i) res.m[i][i] = 1;
        while(b) {
            if(b & 1) res = res * a;
            a = a * a;
            b >>= 1;
        }
        return res;
    }
    LL f[5];
    int main() {
        int ca;ca = read();
        while(ca--) {
            int A,B,C,D,P,n;
            A = read() % Mod,B = read() % Mod,C = read() % Mod,D = read() % Mod,P = read(),n = read();
            f[1] = A,f[2] = B;
            if(n == 1) printf("%lld
    ",f[1]);
            else if(n == 2) printf("%lld
    ",f[2]);
            else {
                LL tmp;
                for(int L = 3,r = 0;L <= n;L = r + 1) {
                    if(P / L == 0) r = n;
                    else r = min(n,P / (P / L));
                   // printf("L is %d r is %d
    ",L,r);
                    int len = r - L + 1;
                    LL k = P / L;
                    Mat ans;memset(ans.m,0,sizeof(ans.m));
                    if(len == 1) {
                        f[3] = D * f[2] % Mod + C * f[1] % Mod + k;
                        f[3] %= Mod;
                        f[1] = f[2];
                        f[2] = f[3];
                        tmp = f[3];
                    }
                    else if(len == 2) { 
                        f[3] = D * f[2] % Mod + C * f[1] % Mod + k;
                        f[3] %= Mod;
                        f[4] = D * f[3] % Mod + C * f[2] % Mod + k;
                        f[4] %= Mod;
                        f[2] = f[4],f[1] = f[3];
                        tmp = f[4];
                    } 
                    else {
                      //  printf("L is %d r is %d f[2] is %lld f[1] is %lld
    ",L,r,f[2],f[1]);
                        f[3] = D * f[2] % Mod + C * f[1] % Mod + k;
                        f[3] %= Mod;
                        f[4] = D * f[3] % Mod + C * f[2] % Mod + k;
                        f[4] %= Mod;
                        Mat a;memset(a.m,0,sizeof(a.m));
                        a.m[1][1] = D,a.m[1][2] = C,a.m[1][3] = 1;
                        a.m[2][1] = 1,a.m[3][3] = 1;
                        ans.m[1][1] = f[4],ans.m[2][1] = f[3],ans.m[3][1] = k;
                        a = quick_mi(a,len - 2);
                        ans = a * ans;
                        f[2] = ans.m[1][1],f[1] = ans.m[2][1];
                        tmp = f[2];
                      //  printf("f[2] is %lld f[1] is %lld
    ",f[2],f[1]);
                    }
                }
                printf("%lld
    ",tmp);
            }
        }
    
    
        system("pause");
        return 0;
    }
    /*
    2 
    1 2 3 4 10 10
    
    */
    View Code

    Swordsman:

    牛马卡快读,普通快读都被卡掉了。。

    我一开始的思路是,对k的全排列排序,然后不断维护每个排列的头,这样如果满足一个大那就肯定能在里面找到一个。

    但是复杂度还是高了点,大概k! * N * k。

    其实没必须对所有全排列排:考虑五个队列。

    每个小顶堆维护一个k的最小。

    我们从第一个开始,如果这个元素的第一值<=v,那么就说明他第一位置满足条件,那就放入第二位置。

    以此类推,到最后一个堆还满足就可以杀掉了。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<LL,int> pii;
    const int N = 1e5 + 5;
    const int M = 4e6 + 5;
    const LL Mod = 199999;
    #define pi acos(-1)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    #define reads(n) FastIO::read(n)
    namespace FastIO {
        const int SIZE = 1 << 16;
        char buf[SIZE], obuf[SIZE], str[60];
        int bi = SIZE, bn = SIZE, opt;
        int read(char *s) {
            while (bn) {
                for (; bi < bn && buf[bi] <= ' '; bi++);
                if (bi < bn) break;
                bn = fread(buf, 1, SIZE, stdin);
                bi = 0;
            }
            int sn = 0;
            while (bn) {
                for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
                if (bi < bn) break;
                bn = fread(buf, 1, SIZE, stdin);
                bi = 0;
            }
            s[sn] = 0;
            return sn;
        }
        bool read(int& x) {
            int n = read(str), bf;
            if (!n) return 0;
            int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
            for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
            if (bf < 0) x = -x;
            return 1;
        }
    };
    
    int v[5],f[5];
    int len[121];
    struct Node{
        int a[5],b[5];
    }p[N];
    bool vis[N];
    struct cmp1 {
        bool operator() (const Node &a,const Node &b) {
            return a.a[0] > b.a[0];
        }
    };
    struct cmp2 {
        bool operator() (const Node &a,const Node &b) {
            return a.a[1] > b.a[1];
        }
    };
    struct cmp3 {
        bool operator() (const Node &a,const Node &b) {
            return a.a[2] > b.a[2];
        }
    };
    struct cmp4 {
        bool operator() (const Node &a,const Node &b) {
            return a.a[3] > b.a[3];
        }
    };
    struct cmp5 {
        bool operator() (const Node &a,const Node &b) {
            return a.a[4] > b.a[4];
        }
    };
    priority_queue<Node,vector<Node>,cmp1> Q1;
    priority_queue<Node,vector<Node>,cmp2> Q2;
    priority_queue<Node,vector<Node>,cmp3> Q3;
    priority_queue<Node,vector<Node>,cmp4> Q4;
    priority_queue<Node,vector<Node>,cmp5> Q5;
    int main() {
        int ca;reads(ca);
        while(ca--) {
            int n,k;reads(n),reads(k);
            while(!Q1.empty()) Q1.pop();
            while(!Q2.empty()) Q2.pop();
            while(!Q3.empty()) Q3.pop();
            while(!Q4.empty()) Q4.pop();
            while(!Q5.empty()) Q5.pop();
            for(int i = 0;i < k;++i) reads(v[i]);
            for(int i = 1;i <= n;++i) {
                for(int j = 0;j < k;++j) reads(p[i].a[j]);
                for(int j = 0;j < k;++j) reads(p[i].b[j]);
                Q1.push(p[i]);
            }
            int kil = 0;
            while(1) {
                int f = 0;
                while(!Q1.empty()) {
                    Node q = Q1.top();
                    if(v[0] >= q.a[0]) {
                        if(k == 1) {
                            f = 1;
                            kil++;
                            for(int j = 0;j < k;++j) {
                                v[j] += q.b[j];
                            }
                        }
                        else Q2.push(q);
                        Q1.pop();
                    } 
                    else break;
                }
                while(!Q2.empty()) {
                    Node q = Q2.top();
                    if(v[1] >= q.a[1]) {
                        if(k == 2) {
                            f = 1;
                            kil++;
                            for(int j = 0;j < k;++j) {
                                v[j] += q.b[j];
                            }
                        }
                        else Q3.push(q);
                        Q2.pop();
                    } 
                    else break;
                }
                while(!Q3.empty()) {
                    Node q = Q3.top();
                    if(v[2] >= q.a[2]) {
                        if(k == 3) {
                            f = 1;
                            kil++;
                            for(int j = 0;j < k;++j) {
                                v[j] += q.b[j];
                            }
                        }
                        else Q4.push(q);
                        Q3.pop();
                    } 
                    else break;
                }
                while(!Q4.empty()) {
                    Node q = Q4.top();
                    if(v[3] >= q.a[3]) {
                        if(k == 4) {
                            f = 1;
                            kil++;
                            for(int j = 0;j < k;++j) {
                                v[j] += q.b[j];
                            }
                        }
                        else Q5.push(q);
                        Q4.pop();
                    } 
                    else break;
                }
                while(!Q5.empty()) {
                    Node q = Q5.top();
                    if(v[4] >= q.a[4]) {
                        f = 1;
                        kil++;
                        for(int j = 0;j < k;++j) {
                            v[j] += q.b[j];
                        }
                        Q5.pop();
                    } 
                    else break;
                }
                if(f == 0) break;
            }
            printf("%d
    ",kil);
            for(int i = 0;i < k;++i) printf("%d%c",v[i],i == k - 1 ? '
    ' : ' ');
        }
    
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    服务端渲染
    node基础
    vue不同组件间的通信
    mui底部导航栏
    在mui中引入自定义的字体图标
    axios的使用
    vue多视图
    多元线性回归:波士顿房价预测问题TesnsorFlow实战
    MNIST手写数字识别:分类应用入门(实践篇)
    7-3 java高级 22_19寻找最大块的问题 (20 分)
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/14843065.html
Copyright © 2011-2022 走看看