• [NOI Online #1 提高组]最小环


    description

    solution:

    又是一道小学奥数神题
    从简单情况开始考虑
    (k=1),不妨考虑(n=6)的情况(其他类似)
    最优情况是(lbrace1,3,5,6,4,2 brace)
    作为一名结论人,大胆猜测构造解的方式:
    首先(6)放在中间,然后交错地再6两边放(5,4,3,2,1)
    为什么这样是最优的呢?
    感性理解的话就是尽量让大的数和大的数相乘,小的数和小的数相乘
    然后dfs验证小数据后发现都是对的,那就不妨假设这个结论是正确的吧
    那如果(k=2)呢?还是先考虑(n=6)的情况
    可以发现位置(2,4,6)和位置(1,3,5)是两个互不干扰的环
    对于每个环,我们就按照之前(k=1)的情况构造就行
    现在要考虑的是每个环究竟放置那些数
    还是那个神必东西:尽量让大的数和大的数相乘,小的数和小的数相乘
    于是相当于把所有数进行排序,然后按照顺序依次加入每一个环,最后把每个环的贡献加起来就是答案了
    因为这样可以保证大的数和大的数在一起
    但是如何求出环的个数呢?
    手动模拟+感性理解可以发现答案就是({gcd(n,i)})其中(i)为询问
    如果每次暴力做一遍显然会超时
    于是我们可以预处理出(n)的所有约数的答案,询问的时候就可以(O(1))做了

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=2e5+5;
    int n,m,a[N];
    ll ans[N];
    inline int read()
    {
    	int s=0,w=1; char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())if(ch=='-')w=-1;
    	for(;isdigit(ch);ch=getchar())s=(s<<1)+(s<<3)+(ch^48);
    	return s*w; 
    }
    inline ll solve(vector<int>&v)
    {
    	vector<int>nx;int sz=v.size();ll anss=0;
    	for(int i=0;i<sz;++i,++i)
    		nx.push_back(v[i]);
    	for(int i=sz-(sz&1?2:1);i>=0;--i,--i)
    		nx.push_back(v[i]);
    	for(int i=1;i<sz;++i)anss+=1ll*nx[i-1]*nx[i];
    	return anss+1ll*nx[sz-1]*nx[0];
    }
    inline void work(int x)
    {
    	if(ans[x])return;
    	vector<int>v;
    	for(int i=1;i<=n;i+=x,v.clear())
    	{
    		for(int j=i;j<i+x;++j)v.push_back(a[j]);
    		ans[x]+=solve(v);
    	}
    }
    inline void pre()
    {
    	sort(a+1,a+n+1);
    	int mx=sqrt(n+0.5)+1;
    	for(int i=1;i<=mx;++i)
    		if(n%i==0)work(i),work(n/i);
    }
    int gcd(int x,int y){return y?gcd(y,x%y):x;}
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	pre();
    	while(m--)
    	{
    		int k=read();
    		printf("%lld
    ",ans[n/gcd(k,n)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    【秋招必备】Redis面试题(2021最新版)
    【秋招必备】Spring Boot面试题(2021最新版)
    【秋招必备】Java基础知识面试题(2021最新版)
    用友二面:如何设计一个高可用、高并发秒杀系统
    万字长文,带你深入理解Java虚拟机!
    小米面试官:说说Spring源码里面的Bean的生命周期!
    苏宁易购三面:写一个脚本获取Linux系统CPU的详细信息,并说出原理!
    易错点。
    APP间传递消息
    KVC, KVO
  • 原文地址:https://www.cnblogs.com/zmyzmy/p/13845764.html
Copyright © 2020-2023  润新知