POJ 3270. Cow Sorting & 51nod 1125 交换机器的最小代价

根据题意,需要交换的部分会形成若干个不相交的环,独立处理每个环。

每个环可以用环内的最小值去和其它元素交换,或者用全局最小值和环上最小值交换,做一遍再交换回去。

#include <cstdio>
#include <cstring>

const int MOD = 9973;
int m, n, k;

void M(int &a) {
    if (a >= MOD) a -= MOD;
    if (a < 0) a += MOD;
}

struct Mat {
    int mat[11][11];
    void clear() {
        memset(mat, 0, sizeof(mat));
    }
    Mat(int x = 0) {
        memset(mat, 0, sizeof(mat));
        for (int i = 1; i <= m; i++)
            mat[i][i] = x;
    }
    Mat operator * (const Mat &p) const {
        Mat c;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= m; j++) {
                int cnt = 0;
                for (int k = 1; k <= m; k++)
                    cnt += mat[i][k] * p.mat[k][j];
                c.mat[i][j] = cnt % MOD;
            }
        return c;
    }
    Mat operator ^ (int b) {
        Mat c(1);
        Mat a = *this;
        while (b) {
            if (b & 1) c = c * a;
            a = a * a;
            b >>= 1;
        }
        return c;
    }
} base, res;

int phi(int n) {
    int ans = n;
    for (int i = 2; i * i <= n; i++) {
        if (n % i == 0) {
            ans -= ans / i;
            while (n % i == 0)
                n /= i;
        }
    }
    if (n > 1)
        ans -= ans / n;
    return ans % MOD;
}

int qp(int a, int b = MOD - 2) {
    int ans = 1;
    a %= MOD;
    while (b) {
        if (b & 1) ans = ans * a % MOD;
        a = a * a % MOD;
        b >>= 1;
    }
    return ans;
}

int solve(int x) {
    res = base ^ x;
    int ans = 0;
    for (int i = 1; i <= m; i++)
        M(ans += res.mat[i][i]);
    return ans;
}

int solve() {
    int ans = 0;
    for (int i = 1; i * i <= n; i++) {
        if (n % i) continue;
        M(ans += 1LL * phi(n / i) * solve(i) % MOD);
        if (i * i == n) continue;
        M(ans += 1LL * phi(i) * solve(n / i) % MOD);
    }
    return ans * qp(n) % MOD;
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        base.clear();
        scanf("%d%d%d", &n, &m, &k);
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= m; j++)
                base.mat[i][j] = 1;
        while (k--) {
            int a, b;
            scanf("%d%d", &a, &b);
            base.mat[a][b] = base.mat[b][a] = 0;
        }
        printf("%d\n", solve());
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Mrzdtz220/p/12231022.html

时间: 2024-10-15 11:01:13

POJ 3270. Cow Sorting & 51nod 1125 交换机器的最小代价的相关文章

51nod 1125 交换机器的最小代价

基准时间限制:1 秒 空间限制:131072 KB 有N台机器重量各不相等,现在要求把这些机器按照重量排序,重量从左到右依次递增.移动机器只能做交换操作,但交换机器要花费一定的费用,费用的大小就是交换机器重量的和.例如:3 2 1,交换1 3后为递增排序,总的交换代价为4.给出N台机器的重量,求将所有机器变为有序的最小代价.(机器的重量均为正整数) Input 第1行:1个数N,表示机器及房间的数量.(2 <= N <= 50000) 第2 - N + 1行:每行1个数,表示机器的重量Wi.(

poj 3270 Cow Sorting 置换群 简单题

假设初始状态为 a:2 3 1 5 4 6 则目标状态为 b:1 2 3 4 5 6且下标为初始状态中的3 1 2 4 5 6(a[3],a[1]...) 将置换群写成循环的形式 (2,3,1),(5,4),6就不用移动了. 移动方式2种 1:选循环内最小的数和其他len-1个数交换 2:选整个序列最小的数和循环内最小的数交换,转到1,再换回来. #include<cstdio> #include<queue> #include<algorithm> #include&

poj 3270 Cow Sorting(初涉置换群)

http://poj.org/problem?id=3270 大致题意:给出n个整数,要将它们转化成递增序列,每交换其中两个数的代价是这两个数之和.问排序成功后的最小代价. 该题考察的是置换群知识.在黑书p247上有详细的讲解.总结下置换群,方便复习. 群:给定一个集合G={a,b,c...}和集合G上的二元运算 ·,如果满足封闭性,结合律,存在单位元和逆元,则成集合G在运算'·'之下是一个群. 置换:n个元素1,2,....,n之间的置换可表示为  1     2     3     ...

POJ 3270 Cow Sorting(置换群)

题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. 思路 : 这个在黑书上有写,就是置换群,248页有写.写的挺详细的.每个状态都可以分为若干个循环的乘积.对于任意循环 i ,设其长度为ki,则至少需要交换ki-1次,即每次让一个元素到达目标位置,而当第ki-1个元素到达目标以后显然第ki个也已经到达目标.第一个方法是让循环中最小的元素t参加所有的交

poj 3270 Cow Sorting

Cow Sorting 题意:有N头牛,每头牛都有不同的暴躁值ai,现在要将所有的牛按照暴躁值从小到大排序,每次交换两个元素(任意交换)时,花费就是两头牛的暴躁值之和:问排序的最小花费为多少? 数据:(1 ≤ N ≤ 10,000) (1 <= ai <= 100,000); 思路:很明显的贪心:(下面讲的循环是置换群里的循环) 策略:我们从没在最终位置且值最小的牛看起,如果每次都是将当前考虑的牛直接与它最终的位置的牛交换,那么这样递推下去,将形成的就是一个循环(一定有牛的最终位置为考虑的起始

POJ 3270 Cow Sorting(置换环)

Cow Sorting Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6393   Accepted: 2476 Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...

[ACM] POJ 3270 Cow Sorting (置换,贪心)

Cow Sorting Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5946   Accepted: 2263 Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...

[51Nod1125] 交换机器的最小代价

题意:N个高度不一的机器,排成一列,为了把他们排成高度递增的一列,每次可以交换两个机器,代价为两个机器的和 题解: 贪心+置换 1.用每个置换内部的最小值交换置换长度减一次,其他点交换一次 2.引入外部的最小点,交换它与内部最小点的位置,交换置换长度+2次后再把内部最小点换回来,其他点交换一次 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<

51nod 1476 括号序列的最小代价 (括号题套路+反悔贪心)

题意:给一串只有'(' , ')' , '?' 的括号序列,每个?可以变成)或者(,代价分别为bi和ai,求变成合法序列的最小代价 思路:学习自最近的网络赛&&51nod贪心专题视频的思想,“反悔”,一般在获取收益有限制的情况下使用 先按某种“优”的策略贪心,如果不满足限制条件了,取一个修改后代价尽可能小的状态修改成满足条件的状态,得到新的满足限制下的最优解 这种贪心常常可以借助优先队列实现 然后是括号题的套路:把(当做1,把)当做-1,做前缀和 这题中,先当做所有的?都换成右括号,这是显