zoukankan      html  css  js  c++  java
  • 【NOI Online 提高组】最小环

    (Solution)

    我们将序列分成几个互不干扰的环。(互不干扰就是一个环以 (k) 无论如何都到不了另一个环)

    可以证明,我们会将其分成 (gcd(n,k)) 个环,每个环会有 (frac{n}{gcd(n,k)}) 个数。(很多人的题解是这么写的,然而蒟蒻本蒻根本看不懂

    我们接下来尝试证明一下:

    首先,如果是一个环的话应该首尾相同。我们设每个环有 (x) 个数。那么就有:(kxequiv0 (mod n))

    我们用 (gcd(n,k))(n)(k) 划分成几个小格子,那么 (frac{n}{gcd(n,k)}) 就是 (n) 有几个这样的小格子。我们将其乘以 (k),肯定是满足 (k) 走几步是能达到的,那么对于 (n),相当是将 (frac{n}{gcd(n,k)}) 个小格子的容量由 (gcd(n,k)) 扩展到了 (k) 个,也是满足前面同余的需求的。(注意必须使之前小格子的容量为 (k) 的因数,这样才能保证倍增)

    接下来我们要保证的是每个环有 (frac{n}{gcd(n,k)}) 个数的时候那个环的每个数只能走一次。(其实这里描述并不准确,因为个数本身就是只出现一次的)

    这个其实很好证,因为 (gcd) 就是最大的公共因数,所以 (frac{n}{gcd(n,k)}) 就是最小的,即 (x)

    然后关于为什么是按顺序放的我就在这里放一个大佬的证明:点此看神仙

    个数固定的一定答案是一样的,我们搞一个记忆化就可以了。(毕竟一个数的因子个数并不多)

    详见代码。

    (Code)

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N = 2e5 + 5;
    
    ll a[N], memo[N], ans;
    int n, m, k; 
    
    int read() {
        int x = 0, f = 1; char s;
        while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
        while(s >= '0' && s <= '9') {x = (x << 1) + (x << 3) + (s ^ 48); s = getchar();}
        return x * f;
    }
    
    int gcd(const int a, const int b) {
    	if(! b) return a;
    	return gcd(b, a % b);
    }
    
    int main() {
    	n = read(), m = read();
    	for(int i = 1; i <= n; ++ i) a[i] = read();
    	sort(a + 1, a + n + 1);
    	while(m --) {
    		k = read();
    		ans = 0;
    		if(k == 0 || n == 1) {
    			for(int i = 1; i <= n; ++ i) ans += a[i] * a[i];
    			printf("%lld
    ", ans);
    			continue;
    		}
    		int t = gcd(n, k), per = n / t;
    		if(memo[per]) {printf("%lld
    ", memo[per]); continue;}
    		for(int i = 1; i <= n; i += per) {
    			for(int j = 0; j < per - 2; ++ j) ans += a[i + j] * a[i + j + 2];//按顺序取,相当是 min,min+2...min+3,min+1 (这是个环)
    			ans += a[i] * a[i + 1] + a[i + per - 1] * a[i + per - 2];//取min与min+1,max与max-1
    		}
    		printf("%lld
    ", ans);
    		memo[per] = ans;
    	}
    	return 0;
    } 
    
  • 相关阅读:
    use paramiko to connect remote server and execute command
    protect golang source code
    adjust jedi vim to python2 and python3
    install vim plugin local file offline
    add swap file if you only have 1G RAM
    datatables hyperlink in td
    django rest framework custom json format
    【JAVA基础】网络编程
    【JAVA基础】多线程
    【JAVA基础】String类的概述和使用
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/12456259.html
Copyright © 2011-2022 走看看