• [补题记录]AtCoder Beginner Contest 175 D


    AtCoder Beginner Contest 175 D - Moving Piece

    题意:

    Takahashi will play a game using a piece on an array of squares numbered (1, 2, cdots, N). Square (i) has an integer (C_i) written on it. Also, he is given a permutation of (1, 2, cdots, N): (P_1, P_2, cdots, P_N).
    Now, he will choose one square and place the piece on that square. Then, he will make the following move some number of times between (1) and (K) (inclusive):

    In one move, if the piece is now on Square (i) ((1 leq i leq N)), move it to Square (P_i). Here, his score increases by (C_{P_i}).

    Help him by finding the maximum possible score at the end of the game. (The score is (0) at the beginning of the game.)

    给你两组序列(N,P),每次对于(1)(n)的每一个(i)你要把Square (i)移到 Square (P_i),然后(i)的score会增长(C_{p_i}),问在这场游戏中能达到的最大score

    题解:

    首先(kleq 10^9)我们肯定不能模拟,按照样例推导一遍是会发现它是有循环节的,也就是说问题简化为了对于每一个(i),有(a_1,a_1+a_2,dots,a_1+a_2+a_3+dots+a_{temp}+a_1+a_2+a_3+dots)(一共k项)中出现过的数的最大值

    那么我们对于每一个(i),把一个循环结存到ve[i]中,ve[i].size()就是循环节的大小

    然后记下来(d=k/len)最多跑多少个循环节 (m=k%len) 最后一个循环节多出来多少个数

    如果一个循环节的总和>0,那我们一定是要把所有的循环节跑完的

        now=d*sum[i];
        for(int j=0;j<m;j++) now+=ve[i][j],ans=max(ans,now);
    

    还有就是如果(m==0),那(d--;m=len;)保留最后一次循环节

    如果一个循环节的总和<=0,那我们选了这个循环节还不如不选,只对(0)(d==0?m:ve[i].size())取个最优即可

    唔 貌似别忘了还要开个long long

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a) & -(a))
    #define clean(a, b) memset(a, b, sizeof(a))
    const int mod = 998244353;
    const int inf = 0x3f3f3f3f;
    const int maxn = 2e5 + 9;
    // typedef pair<int,int>P;
    
    int _;
    
    //========================================================================
    ll Pp[maxn],Cc[maxn],mp[5009];
    ll a[maxn],sum[maxn];
    vector<ll>ve[5009];
    //========================================================================
    int main()
    {
        ll n,k;
        ll x;
        scanf("%lld%lld",&n,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            Pp[i]=a[i];
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&x);
            Cc[i]=x;
        }
        ll ans=-1e18;
        for(ll i=1;i<=n;i++)
        {
            ll now=i;
            clean(mp,0);
            while(1)
            { 
                now=Pp[now];
                if(mp[now]==1) break;
                mp[now]=1;
                sum[i]+=Cc[now];
                ve[i].push_back(Cc[now]);
            }
            int len=ve[i].size();
            ll d=k/len;
            ll m=k%len;
            now=0;
            if(sum[i]>0) 
            {
                if(m==0) 
                {
                    now=(d-1)*sum[i];
                    m=len;
                }
                else now=d*sum[i];
                for(int j=0;j<m;j++) now+=ve[i][j],ans=max(ans,now);
            }
            else 
            {
                if(d==0)
                {
                    for(int j=0;j<m;j++) now+=ve[i][j],ans=max(ans,now);
                }
                else 
                {
                    for(int j=0;j<len;j++) now+=ve[i][j],ans=max(ans,now);
                }
            }
        }
        // for(int i=1;i<=n;i++)
        // {
        //     int len=ve[i].size();
        //     for(int j=0;j<len;j++) printf("%lld ",ve[i][j]);
        //     printf("
    ");
        // }
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    阶段一 第一周 2-5 2-6 构建maven聚合工程
    阶段一 第一周 2-3 前后端分离开发模式讲解
    阶段一 第一周 2-2前后端技术选型
    Linux基础
    SpringMVC复习
    电商航线整理
    Mybatis整理复习
    python re正则
    爬虫基础 简单正则
    mysql 备份 恢复 事物 ER模型 pymysql交互
  • 原文地址:https://www.cnblogs.com/YangKun-/p/13521371.html
Copyright © 2020-2023  润新知