• hdu 4611 Balls Rearrangement


    http://acm.hdu.edu.cn/showproblem.php?pid=4611

    从A中向B中移动和从B中向A中移动的效果是一样的,我们假设从B中向A中移动 而且A>B

    我们先求出所有在B[0]上的点移动到A上的分布情况 可以求出花费

    当我们要求B[1]上的点移动到A上的分布情况时 相当于B[0]在A上的分布情况水平右移一个单位

    由于B[1]点对于B[0]也向后移动了一个单位 所有相对位置没有移动

    但是A中有一个地方需要改动 那就是每次A中最后一个位置的点需要移动到A[0]位置(因为对A进行取模的原因)

    还有一个要注意的情况就是 B 在向后移动的时候 点的个数可能会减小 要特殊处理一下

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<map>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<queue>
    #include<bitset>
    #include<deque>
    #include<numeric>
    
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned int uint;
    typedef pair<int,int> pp;
    const double eps=1e-9;
    const int INF=0x3f3f3f3f;
    const ll MOD=1000000007;
    const int H=210000;
    const int K=100001;
    ll a[H];
    int f(int x)
    {
        return x+K;
    }
    ll readya(ll N,ll A,ll B)
    {
        ll lcm=A*B/(__gcd(A,B));
        int n=lcm/B;
        int k=0;
        ll num=(N/B);
        if(N%B) ++num;
        for(int i=0;i<n;++i)
        {
            a[f(k)]+=num/n;
            k=(k+B)%A;
        }
        ll M=num%n;
        k=0;
        while(M--)
        {
            a[f(k)]++;
            k=(k+B)%A;
        }
        ll tmp=0;
        for(int i=1;i<A;++i)
        tmp+=a[f(i)]*i;
        return tmp;
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(a,0,sizeof(a));
            ll N,A,B;
            cin>>N>>A>>B;
            if(B>A) swap(A,B);
            if(A==B)
            {printf("0
    ");continue;}
            ll L=0;
            ll R=readya(N,A,B);
            int num=N/B;
            if(N%B) ++num;
            ll ans=L+R;
            for(int i=1;i<B;++i)
            {
                a[f(-i)]=a[f(A-i)];
                R-=(a[f(A-i)]*(A-i));
                L+=(a[f(-i)]*i);
                a[f(A-i)]=0;
                int tmp=(N-i)/B;
                if((N-i)%B) ++tmp;
                if(tmp!=num)
                {
                    int x=tmp*B+i;
                    a[f(x%A-i)]--;
                    if(x%A-i>0) {R-=abs(x%A-i);}
                    if(x%A-i<0) {L-=abs(x%A-i);}
                    num=tmp;
                }
                ans+=(L+R);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    Socket listen 简要分析
    Socket connect 等简要分析
    HIVE函数大全
    元数据管理
    flume
    shell编程
    数据仓库集锦
    数据库知识
    hive sql 转化mapreduce原理
    Hadoop 学习笔记
  • 原文地址:https://www.cnblogs.com/liulangye/p/3216732.html
Copyright © 2020-2023  润新知