zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU5637 Transform(数论 && 最短路)

    题目链接:http://codeforces.com/problemset/problem/590/A

    题目大意是给两种操作,然后给你一个s,一个t,求s至少需要多少次操作到t

    考虑到第一种操作是将某一位取反,而第二种操作是抑或一个数。

    显然第一种操作也是可以通过抑或一个数得到的。比如:第i位取反,相当于抑或(1<<i)这个数。于是就将n个数扩大到n+17就可以了,因为100000最多17位。

    此外如果p^a^b^c...=q的话,那么a^b^c...=p^q。于是,只需要求出p^q至少需要几个数抑或而成就可以了。

    然后跑一个类似于最短路就可以了,此处采用spfa

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    #define MOD 1000000007
    
    using namespace std;
    
    int n, m, a[50];
    int dis[200005];
    bool vis[200005];
    
    void input()
    {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; ++i)
            scanf("%d", &a[i]);
        for (int i = 0; i < 17; ++i)
            a[i+n] = 1<<i;
        n += 17;
        //spfa
        memset(dis, -1, sizeof(dis));
        dis[0] = 0;
        memset(vis, false, sizeof(vis));
        vis[0] = true;
        queue<int> q;
        q.push(0);
        int k, v, t;
        while (!q.empty())
        {
            k = q.front();
            q.pop();
            vis[k] = false;
            for (int i = 0; i < n; ++i)
            {
                v = k^a[i];
                if (dis[v] != -1 && dis[v] <= dis[k]+1)
                    continue;
                dis[v] = dis[k]+1;
                if (!vis[v])
                {
                    q.push(v);
                    vis[v] = true;
                }
            }
        }
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        for (int times = 1; times <= T; ++times)
        {
            input();
            int s, t;
            LL ans = 0;
            for (int i = 1; i <= m; ++i)
            {
                scanf("%d%d", &s, &t);
                ans += (LL)i*dis[s^t];
                ans %= MOD;
            }
            cout << ans << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java json 库之 jackson
    java 多线程
    golang slice 和 string 重用
    golang 字节对齐
    golang 并发编程之生产者消费者
    golang 设计模式之选项模式
    golang aws-sdk-go 之 s3 服务
    markdown 一个优雅的写作工具
    常见句型、用法
    hg
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/5245987.html
Copyright © 2011-2022 走看看