首页 > 其他分享 >题解:AT_arc120_c [ARC120C] Swaps 2

题解:AT_arc120_c [ARC120C] Swaps 2

时间:2024-10-14 19:00:54浏览次数:8  
标签:Swaps int 题解 mid merge 序列 操作 arc120

Problem Link

[ARC120C] Swaps 2

\(-1\) 的情况判错卡了 \(10\) 几分钟,麻了。

题面翻译

给出 \(2\) 个序列 \(a\) 和 \(b\),定义一次操作为:

  • 选定一个下标 \(i\),先将 \(a_i\) 以及 \(a_{i+1}\) 交换,然后让 \(a_i\) 加一,最后让 \(a_{i+1}\) 减一。

求最少操作次数使得 \(a\) 序列等于 \(b\) 序列,否则输出 -1

Solution

手动模拟几次操作之后,发现:

\(a_i\) 经过一次操作后变成的 \(a_{i+1}+i+1\) 不会变。

举个栗子:\(a_1 = 4\),\(a_2 = 6\),对 \(a_1\) 进行操作,\(a_1 = 7\),\(a_2 = 3\),\(1+4 = 2+3\)。

由于结论显然,这里不作证明了。

于是问题便转化为了:

给出 \(2\) 个序列 \(a\) 和 \(b\),每次操作你可以交换 \(a\) 中相邻的 \(2\) 个数,求使 \(a\) 等于 \(b\) 的最小操作次数。

这是个小 \(trick\),该问题可转化为求逆序对个数,这里使用归并排序求逆序对数,时间复杂度为 \(O(n \times \log_{2}{n})\)。

至于判断负数,有 \(2\) 种情况:

  • 两个序列总和不同。(因为操作不影响序列的总和)

  • 转化过后的 \(a\) 序列和 \(b\) 序列有不同数字。

其实第 \(1\) 种情况本质上就是第 \(2\) 种情况。

至于如何处理,将 \(a\) 中数字放入 map 中计数,再在 \(b\) 中判断即可。

代码

// written by Naught
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define Maxn 200005
#define fo(i, l, r) for (int i = l; i <= r; ++i)
#define fr(i, r, l) for (int i = l; i >= r; --i)
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21], *p1 = buf, *p2 = buf;
inline int read(int x=0, bool f=0, char c=getchar()) {for(;!isdigit(c);c=getchar()) f^=!(c^45);for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48);return f?-x:x;}

int n, sum_cnt, a[Maxn], b[Maxn], A[Maxn], B[Maxn], c[Maxn];
ll sum, ans;
map<int, queue<int>> mp;
map<int, int> cnt;

void merge_sort(int l, int r)
{
    if ( l == r ) return;
    int mid = (l + r) >> 1, i = l, j = mid+1, k = l;
    merge_sort( l , mid );
    merge_sort( mid+1 , r );
    while ( i <= mid && j <= r )
    	if(a[i] <= a[j]) c[k++] = a[i++];
    	else c[k++] = a[j++], ans += mid-i+1;
    while ( i <= mid ) c[k++] = a[i++];
    while ( j <= r ) c[k++] = a[j++];
    fo(i, l, r) a[i] = c[i];
} 

signed main()
{
    n = read();
    fo(i, 1, n) a[i] = read(), A[i] = a[i]+i, sum += a[i], ++cnt[A[i]], sum_cnt += cnt[A[i]] == 1;
    fo(i, 1, n) b[i] = read(), B[i] = b[i]+i, mp[B[i]].push(i), sum -= b[i], --cnt[B[i]], sum_cnt -= cnt[B[i]] == 0;
    if(sum_cnt || sum) return puts("-1"), 0;
    fo(i, 1, n) a[i] = mp[A[i]].front(), mp[A[i]].pop();
    merge_sort(1, n);
    printf("%lld", ans);
    return 0;
}

标签:Swaps,int,题解,mid,merge,序列,操作,arc120
From: https://www.cnblogs.com/naughty-naught/p/18464776

相关文章

  • 题解:[HNOI2009] 双递增序列
    ProblemLink[HNOI2009]双递增序列题目描述给定一个长度为\(n\)的序列(\(n\)为偶数),求是否可以把序列分成\(2\)个长度为\(\frac{n}{2}\)的递增序列。Solution首先想到定义\(f_i\)为一个序列以\(a_i\)结尾时另一个序列末尾最小值。但这样定义状态信息是不够的,考虑......
  • qoj6562 First Last 题解
    妙妙题。首先不同字母数最多为\(3\)。我们把每一个字母看成一个点。对于每一个字符串,首个字母朝末尾字母连一条有向边。那么问题变为了给定一张有向图,从某个点出发,每次走一条边,且边不能重复,不能走的人输。问哪方有必胜策略。先不考虑时间复杂度,那么这个可以直接爆搜。但是肯定......
  • 题解:P11063 【MX-X4-T3】「Jason-1」数对变换
    ProblemLink【MX-X4-T3】「Jason-1」数对变换题外话场上把贪心注重在一个奇怪地方了,导致交的时候已经有\(9\)个人\(\textcolor{green}{AC}\)了(哭)。题意简述对于数对\((x,y)\),你可以执行以下两种变换:类型1:取\(1\lek\lex\),令\((x,y)\gets(\lfloor\frac{x}{k}......
  • 题解:P10370 「LAOI-4」Mex Tower (Hard ver.)
    ProblemLink「LAOI-4」MexTower(Hardver.)题意给定一个长度为$n$的序列$a$,求序列的$\operatorname{Mex}$值是否大于等于其他所有长度为$n$的自然数序列的$\operatorname{Mex}$值。Solution不难发现,两个数或一个序列的$\operatorname{Mex}$一定是......
  • 题解:擬二等辺三角形
    ProblemLink擬二等辺三角形题面翻译定义一个三角形为“伪等腰三角形”需满足以下三个条件:三边长度都为自然数。三边长度各不相同。有其中两条边的长度之差为\(1\)。现在给你一个数\(n\),求周长小于等于\(n\)的“伪等腰三角形”个数,答案对\(1000000007\)取模......
  • 题解:AT_abc370_c [ABC370C] Word Ladder
    题目传送门luogu观看简要题意给两个序列\(S\)和\(T\),输出的第一个数是它能改变的总个数,后面跟着的第\(i\)个是改变\(i\)个数之后,字典序最小的结果。思路当\(S\)与\(T\)相等的话,那就无法改变了,直接输出\(0\)。对于总数只要\(T_i\neS_i\)那它就可以改,所以只......
  • 题解:P1660 数位平方和
    ProblemLinkStep1:“定义\(S(n)\)表示\(n\)个的各个数位的\(k\)次方的和。”数位的\(k\)次方,我们可以通过快速幂求出,为了节省时间,我们可以定义一个\(a\)数组,来表示\(0\sim9\)区间中各数字\(k\)次方的值。然后我们通过定义一个\(s\)数组来存储\(0\sim4\times......
  • 题解:P7356 「PMOI-1」游戏
    ProblemLink「PMOI-1」游戏题意给你一个胜利规则为黑白白白的棋类游戏,你执白,黑先行且第一步必下\((0,0)\),双方皆可放弃落子且落子坐标必须为自然数,请在4步内获胜。思路在自己与自己对下几局之后,有几个显然的发现:黑棋会尽量阻止你4步获胜。在你不会再下一步就获......
  • 题解:AT_agc027_b [AGC027B] Garbage Collector
    ProblemLink[AGC027B]GarbageCollector题意原题翻译已经很不错了,这里不再赘述。思路推论:每次取的垃圾数量应尽可能均分。证明如图,假设有\(4\)个垃圾需要被捡起,有两种取法:取一号垃圾+取二三四号垃圾。取一二号垃圾+取二三号垃圾。前者所需能量为:\(\display......
  • [2024领航杯] Pwn方向题解 babyheap
      [2024领航杯]Pwn方向题解babyheap前言:当然这个比赛我没有参加,是江苏省的一个比赛,附件是XiDP师傅在比赛结束之后发给我的,最近事情有点多,当时搁置了一天,昨天下午想起来这个事情,才开始看题目,XiDP师傅说是2.35版本的libc,确实高版本libc的却棘手,我经验太浅了调试半天,最后让我们......