生活随笔
收集整理的這篇文章主要介紹了
AtCoder Regular Contest 120 C - Swaps 2 线段树模拟
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
傳送門
文章目錄
題意:
給你兩個(gè)序列a,ba,ba,b,每次可以執(zhí)行一個(gè)操作:將a[i]a[i]a[i]與a[i+1]a[i+1]a[i+1]交換,且讓交換后的a[i]+1,a[i+1]?1a[i]+1,a[i+1]-1a[i]+1,a[i+1]?1,問將aaa變成bbb的最小操作數(shù)。不能變成的話輸出?1-1?1。
思路:
考慮將ai=ai+i,bi=bi+ia_i=a_i+i,b_i=b_i+iai?=ai?+i,bi?=bi?+i,如果有解的話那么這兩個(gè)序列必須相同。證明不是很明白,待補(bǔ)。
之后就是裸題了,用線段樹維護(hù)一下位置求出來就好了。
#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
;
typedef long long LL
;
typedef unsigned long long ULL
;
typedef pair
<int,int> PII
;const int N
=1000010,mod
=1e9+7,INF
=0x3f3f3f3f;
const double eps
=1e-6;int n
;
int a
[N
],b
[N
];
map
<int,vector
<int>>v
;
struct Node {int l
,r
;LL cnt
,lazy
;
}tr
[N
<<2];void pushdown(int u
) {if(!tr
[u
].lazy
) return;LL lazy
=tr
[u
].lazy
; tr
[u
].lazy
=0;tr
[L
].lazy
+=lazy
; tr
[R
].lazy
+=lazy
;tr
[L
].cnt
+=lazy
; tr
[R
].cnt
+=lazy
;
}void build(int u
,int l
,int r
) {tr
[u
]={l
,r
,1,0};if(l
==r
) {tr
[u
].cnt
=l
;return;}build(L
,l
,Mid
); build(R
,Mid
+1,r
);
} void change(int u
,int l
,int r
,int c
) {if(tr
[u
].l
>=l
&&tr
[u
].r
<=r
) {tr
[u
].cnt
+=c
;tr
[u
].lazy
+=c
;return;}pushdown(u
);if(l
<=Mid
) change(L
,l
,r
,c
);if(r
>Mid
) change(R
,l
,r
,c
);
}int query(int u
,int l
,int r
) {if(tr
[u
].l
>=l
&&tr
[u
].r
<=r
) return tr
[u
].cnt
;int ans
=0;pushdown(u
);if(l
<=Mid
) ans
+=query(L
,l
,r
);if(r
>Mid
) ans
+=query(R
,l
,r
);return ans
;
}LL
solve() {LL ans
=0;build(1,1,n
);for(int i
=1;i
<=n
;i
++) {int pos
=v
[b
[i
]].back(); v
[b
[i
]].pop_back();LL now
=query(1,pos
,pos
);ans
+=now
-i
;change(1,1,pos
,1);}return ans
;
}bool check() {map
<int,int>mp1
,mp2
;for(int i
=1;i
<=n
;i
++) mp1
[a
[i
]]++;for(int i
=1;i
<=n
;i
++) mp2
[b
[i
]]++;for(int i
=1;i
<=n
;i
++) if(mp1
[a
[i
]]!=mp2
[a
[i
]]) return false;return true;
}int main()
{
int _
=1;while(_
--) {cin
>>n
;for(int i
=1;i
<=n
;i
++) scanf("%d",&a
[i
]),a
[i
]+=i
;for(int i
=1;i
<=n
;i
++) scanf("%d",&b
[i
]),b
[i
]+=i
;for(int i
=n
;i
>=1;i
--) v
[a
[i
]].pb(i
);if(!check()) {puts("-1");return 0;}printf("%lld\n",solve());}return 0;
}
總結(jié)
以上是生活随笔為你收集整理的AtCoder Regular Contest 120 C - Swaps 2 线段树模拟的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。