《2018 Multi-University Training Contest 7》

Age of Moyu:

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

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

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

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

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

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

《2018 Multi-University Training Contest 7》
#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\n",dis[n].first == INF ? -1 : dis[n].first);
    }

   // system("pause");
    return 0;
}
View Code

Sequence:

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

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

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

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

《2018 Multi-University Training Contest 7》
#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\n",f[1]);
        else if(n == 2) printf("%lld\n",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\n",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\n",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\n",f[2],f[1]);
                }
            }
            printf("%lld\n",tmp);
        }
    }


    system("pause");
    return 0;
}
/*
2 
1 2 3 4 10 10

*/
View Code

 

上一篇:CVPR 2021最佳论文奖的候选名单,华人占据半壁*,何恺明、陶大程、沈春华等人上榜义目录标题)


下一篇:《2018 Multi-University Training Contest 8》