逝者如斯夫,不捨晝夜!
葉良辰認為,他的壽命是無限長的,而且每天都會進步。
葉良辰的生命的第一天,他有1點能力值。第二天,有2點。第n天,就有n點。也就是s[i]=i
但是調皮的小a使用時光機,告訴他第x天和第y天,就可以任意交換某兩天的能力值。即s[x]<-->s[y]
小a玩啊玩,終於玩膩了。
葉良辰:小a你給我等著,我有100種辦法讓你生不如死。除非能在1秒鐘之內告知有多少對「異常對」。也就是說,最後的能力值序列,有多少對的兩天x,y,其中xs[y]?
小a:我好怕怕啊。
於是找到了你。
輸入格式:
第一行乙個整數k,表示小a玩了多少次時光機
接下來k行,x_i,y_i,表示將s[x_i]與s[y_i]進行交換
輸出格式:
有多少「異常對」
輸入樣例#1:複製
2輸出樣例#1:複製4 21 4
4樣例說明
最開始是1 2 3 4 5 6...
然後是 1 4 3 2 5 6...
然後是 2 4 3 1 5 6...
符合的對是[1 4] [2 3] [2 4] [3 4]
對於30%的資料,x_i,y_i <= 2000
對於70%的資料, x_i,y_i <= 100000
對於100%的資料, x_i.y_i <= 2^31-1 k<=100000
q1.為什麼76行的x是hash[i+1]-hash[i]-1
a1.因為即使離散化了,但是兩個數之中的數沒有被交換,還是原來的那些數。舉例:
比如 1 2 3 4 5 6 7 8
交換 4 7
交換 1 4
-> 7 2 3 1 5 6 4 8
但是之間還是5,6
q2.為什麼87行是change(i,x),而不是change(i,1),也不是change(a[i],x)
a2.因為既然他們之間有x個數,樹狀陣列求sum的時候必須要將其計算在內,所以把他們加在他們開始的數的編號i上,這樣在計算某數前比他大的數的個數時,就可以一次性加上x個比他大的數。至於為什麼不是change(a[i],1),參見a1.
#include#define f(i,l,r) for(i=(l);i<=(r);i++)
#define ff(i,r,l) for(i=(r);i>=(l);i--)
using namespace std;
const int maxn=100005;
struct nodee[maxn];
int k;
long long t[maxn];
int a[maxn<<1],h[maxn<<1],b[maxn],l;
inline int lowbit(int x)
inline void add(int x,long long d)
return;
}inline long long query(int x)
return res;
}int main()
sort(h+1,h+1+k+k);
l=unique(h+1,h+1+k+k)-(h+1);
f(i,1,l)
f(i,1,k)
ff(i,l,1)
cout
}
洛谷P2448 無盡的生命 樹狀陣列
給出231 12 1 231 1範圍的1 n 1 n1 n的數列,然後有不超過k 1 e5 k leq1e5 k 1e 5次交換,求問最終的逆序對的個數是多少。被交換的值不超過2k2k 2k個,然後再考慮中間一段連續的數對逆序對的貢獻,把他們看作是同乙個點。樹狀陣列維護即可。includeusing...
洛谷2448 無盡的生命
題目 分析 首先離散化,然後樹狀陣列求所有操作過的數產生的逆序對,再求每個操作過的數與沒操作過的數產生的逆序對,因為原始序列有序,所以很方便。include include include include using namespace std const int tmax 200005 struc...
洛谷 2448 無盡的生命
逝者如斯夫,不捨晝夜!葉良辰認為,他的壽命是無限長的,而且每天都會進步。葉良辰的生命的第一天,他有1點能力值。第二天,有2點。第n天,就有n點。也就是s i i 但是調皮的小a使用時光機,告訴他第x天和第y天,就可以任意交換某兩天的能力值。即s x s y 小a玩啊玩,終於玩膩了。葉良辰 小a你給我...