涵涵有兩盒火柴,每盒裝有 nn 根火柴,每根火柴都有乙個高度。 現在將每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 兩列火柴之間的距離定義為:
其中 a_iai 表示第一列火柴中第 ii 個火柴的高度, b_ibi 表示第二列火柴中第 ii 個火柴的高度。
每列火柴中相鄰兩根火柴的位置都可以交換,請你通過交換使得兩列火柴之間的距離最小。請問得到這個最小的距離,最少需要交換多少次?如果這個數字太大,請輸出這個最小交換次數對 99,999,99799,999,997 取模的結果。
輸入格式:
共三行,第一行包含乙個整數 nn ,表示每盒中火柴的數目。
第二行有 nn 個整數,每兩個整數之間用乙個空格隔開,表示第一列火柴的高度。
第三行有 nn 個整數,每兩個整數之間用乙個空格隔開,表示第二列火柴的高度。
輸出格式:
乙個整數,表示最少交換次數對 99,999,99799,999,997 取模的結果。
輸入樣例#1:複製
4
2 3 1 4
3 2 1 4
輸出樣例#1:複製
1
輸入樣例#2:複製
4
1 3 4 2
1 7 2 4
輸出樣例#2:複製
2
【輸入輸出樣例說明1】
最小距離是 0 ,最少需要交換 1次,比如:交換第 1列的前 2 根火柴或者交換第 2 列的前 2 根火柴。
【輸入輸出樣例說明2】
最小距離是 10 ,最少需要交換 2 次,比如:交換第 1 列的中間 2 根火柴的位置,再交換第 2 列中後 2 根火柴的位置。
【資料範圍】
對於 10% 的資料, 1 ≤ n ≤ 101≤n≤10 ;
對於 30% 的資料, 1 ≤ n ≤ 1001≤n≤100 ;
對於 60% 的資料, 1 ≤ n ≤ 1,0001≤n≤1,000 ;
對於 100% 的資料, 1 ≤ n ≤ 100,000,0 ≤1≤n≤100,000,0≤ 火柴高度 ≤ maxlongint≤maxlongint
首先對這個式子進行分析。
最後要使這個最小,我們可以先對
假設原始數列為:
我們如果使得交換之後更優,即
將這個式子進行簡單的化簡之後可以得到
但是要使得交換次數最少,就不能這樣了。
我們可以發現,這個答案其實是把a陣列的數構造成與b陣列一樣在第i位置的數在自己的陣列中是一樣的第k大。
所以我們只要構造出這樣的陣列求出逆序對,逆序對的大小就是a陣列變成成與b陣列一樣第i位置第k大的交換次數。
#include #include #include #include using namespace std;
typedef long long ll;
const int maxn=1e6+5;
const int mod=99999997;
ll a[maxn];
ll b[maxn];
int d[maxn];
struct node
q[maxn],p[maxn];
bool cmp(node a,node b)
int lowbit(int i)
void update(int x,ll *c)
}ll query(int x,ll *c)
return ans;
}int main()
for(int i=1;i<=n;i++)
sort(q+1,q+1+n,cmp);
sort(p+1,p+1+n,cmp);
for(int i=1;i<=n;i++)
ll ans=0;
for(int i=1;i<=n;i++)
printf("%lld\n",ans);
return 0;
}
洛谷P1966 火柴排隊(樹狀陣列)
題目描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 ai bi 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交...
洛谷 P1966 火柴排隊
題目描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 ai bi 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交...
洛谷P1966 火柴排隊
涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 sum a i b i 2 其中a i表示第一列火柴中第 i 個火柴的高度,b i表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交...