對於一對 $(x, y)$,能成為逆序對的取決於絕對值大的那個數的符號。
假如 $a[x] > a[y]$,當 $a[x]$ 為正時,不管 $a[y]$ 取不取負號都比 $a[x]$ 小。
當 $a[x]$ 為負時, 不管 $a[y]$ 取不取負號都比 $a[x]$ 大。
那麼就變成了統計每個節點的子樹及祖先有多少個比它的權值小的。取正時,子樹內權值比它小的節點對答案有貢獻,取負時,祖先中權值比它的節點對答案有貢獻。
然後就相當於01揹包了。
用bitset優化一下複雜度就是 $o(\dfrac)$
求子樹內和到根的路徑上比該節點小的數可以樹剖做。但看了tangjz的**發現乙個更加巧妙的方法。
求子樹內顯然可以從小到大插入節點+dfs序+樹狀陣列。
求該節點到根的路徑上比自己權值大的,就相當於求自己有幾個祖先,相當於求自己在多少個節點的子樹內。
那麼多開乙個樹狀陣列,在插入乙個節點時,讓其子樹這個區間(不包括自身)區間加一。查詢時單點查值就行了。
#include usingview codenamespace
std;
const
int n = 1e5 + 7
;bitset
<30001>mask;
intn;
struct
bit
void add(int x, int
v)
int query(int
x) } bit[2];
int a[n], in[n], out
[n], tol, o[n];
vector
g[n];
void dfs(int u, int
fa)
bool cmp(const
int &x, const
int &y)
intmain()
sort(o + 1, o + n + 1
, cmp);
for (int i = 1; i < n; i++)
dfs(
1, -1
); mask.
set(0
);
for (int i = 1; i <= n; i++)
intq;
scanf("%d
", &q);
while (q--)
return0;
}
牛客挑戰賽58
前i 1的二進位制相等,a的前n個數的前i 1位可以亂取,b的前n 1個數前i 1位也可以亂取,因為b的第n個數的前i 1異或可為任意值,所以sum1 2 i 1 n 2 i 1 n 1 2 i 1 2n 1 a的第i位為1且b的第i位為0 只要a的n數第i位中有乙個不為0的,a的第i位不為0,b的...
牛客挑戰賽45 E 旁觀者
構造乙個 n 個點,m 條邊的仙人掌,使得隨機刪 k 個點之後期望的連通塊個數盡量大。輸出這個最大的期望的連通塊數。n,m,k le 10 9 神仙題。我的1h 考慮正難則反,最終 連通塊數 點數 邊數 環數 點數和邊數可以算,於是我們希望最大化最終剩下的期望環數。這時候可以感覺到欽定每個環長度為 ...
牛客網wannafly挑戰賽13 E 線段樹
時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld vvq 最近迷上了線段這種東西 現在他手上有 n 條線段,他希望在其中找到兩條有公共點的線段,使得他們的異或值最大。定義線段的異或值為它們並的長度減他們交的長度 第...