CF819B Mister B and PR Shifts 思维 + 模拟

link
在这里插入图片描述
思路: 涉及绝对值,我们分为两类数来看,第一类是 p i − i > 0 p_i-i>0 pii>0 第二类是 p i − i < = 0 p_i-i<=0 pii<=0

记zcnt为第一类个数,ztot为第一类的贡献。fcnt为第二类个数,ftot为第二类的贡献。

先不考虑边界情况,对于右移一位 i 会增加1,第一类数 ztot - zcnt,第二类数 ftot + fcnt。当然随着移动会有第一类数变成第二类数的情况,我们用 te 数组记录一下什么时候会改变,让后减去对应的 cnt 即可。

考虑移动的时候当前最后一位数移动到第一位,特判一下就好啦,由于在最后一位一定是第二类数,所以要减去这个数第二类中的贡献。

再就是把数组开大点就好了。

//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;

//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N=4000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n;
int p[N],te[N];
LL ztot,zcnt,ftot,fcnt;

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&p[i]);
        if(p[i]-i>0)
        {
            zcnt++;
            ztot+=p[i]-i;
            te[p[i]-i]++;
        }
        else
        {
            fcnt++;
            ftot+=(i-p[i]);
        }
    }
    LL ans=ftot+ztot,id=0;
    for(int i=1;i<n;i++)
    {
        ztot-=zcnt;
        zcnt-=te[i];
        ftot+=fcnt;
        fcnt+=te[i];
        int x=p[n-i+1];
        ftot-=n+1-x; fcnt--;
        if(x>1) te[x-1+i]++,ztot+=x-1,zcnt++;
        else fcnt++;
        if(ans>ztot+ftot) ans=ztot+ftot,id=i;
    }
    printf("%lld %lld\n",ans,id);



















	return 0;
}
/*

*/









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个关于字符串操作的问题。我们可以逐步模拟过程来求解。 首先,我们可以观察到每次操作后,字符串 $s$ 的长度会增加 $b$,且最后 $a$ 个字符会被替换成新的字符。所以,我们可以通过计算 $l$ 和 $r$ 与每次操作的长度关系来确定最终字符串的长度。 假设经过 $k$ 次操作后,字符串 $s$ 的长度为 $n$,其中 $n \geq a$。那么有 $n = a + k \cdot b$。 接下来,我们计算 $l$ 和 $r$ 在第 $k$ 次操作后的位置。由于每次操作后 $a$ 个字符会被替换,所以在第 $k$ 次操作后,$l$ 和 $r$ 的位置会发生变化。具体而言,$l$ 和 $r$ 在第 $k$ 次操作后的位置为 $l' = l - (k-1) \cdot b$ 和 $r' = r - (k-1) \cdot b$。 现在我们可以将问题分为三种情况来讨论: 1. 如果 $l' > n$,则说明第 $l$ 到第 $r$ 个字符都在每次操作后被替换掉了,所以最少有 $0$ 个不同的字符。 2. 如果 $r' \leq a$,则说明第 $l$ 到第 $r$ 个字符都在每次操作后保持不变,所以最少有 $r' - l' + 1$ 个不同的字符。 3. 如果 $l' \leq n$ 且 $r' > a$,则说明第 $l$ 到第 $r$ 个字符在第 $k$ 次操作后发生了变化。 对于第 $k$ 次操作后的字符串,我们可以观察到每个字符在 $a$ 个字符中的位置是固定的。假设 $t$ 中的字符按顺序为 $t_1, t_2, \dots, t_a$,则第 $l'$ 到第 $r'$ 个字符中最少有 $r' - l' + 1 - (a - (t_{l' \mod a}, t_{(l'+1) \mod a}, \dots, t_{r' \mod a}}))$ 个不同的字符。 综上所述,我们可以根据以上思路编写代码来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值