珂朵莉的數列 (離散化 樹狀)

2022-08-10 08:39:14 字數 1326 閱讀 4697

題意 :

範圍:n<=106,0<=ai<=109

題解:1.轉換角度:子區間有近n*n個,直接求每個區間內的逆序對個數會超時,不如試著求每對逆序對(a[i],a[j])在多少個區間內,並且我們可以推出這個數量=i*(n-j+1)

2.樹狀陣列:直接列舉求乙個序列中所有的逆序對,再計算每對的數量,複雜度o(n2),而樹狀陣列只能求出每個數有多少對逆序對,但是根據上面的規律可以得到每個數在所有區間各自逆序對的總數 =(sum(n)-sum(j))*(n-j+1),樹狀陣列每個值不再只是記錄該元素是否存在,而是每個元素可以存在在多少個區間內,tree[i]=1 —》tree[i]=i;複雜度o(n*log(n))---n次詢問

3.離散化:樹狀陣列需要直接利用每個元素作為下標來記錄資料,但是該題的元素範圍已經超過了陣列可以表示的空間範圍,所以需要離散化,將109的數縮小到105之內,o(log(n))

4.注意:答案可能超過109*109*109,需要用到__int128.

code:

1 #include2 #include

3 #include4 #include5 #include6

using

namespace

std;

7typedef __int128 ll;

8#define lowbit(x) (x&(-x))

9int a[1100000],l[1100000

],cnt,cntt;

10 ll tree[1100000

];11

void add(int x,int

d)16

}17 ll sum(int

x)23

return

ans;24}

25 inline void

write(__int128 x)

2632

if(x>9

)33 write(x/10

);34 putchar(x%10+'0'

);35}36

intmain()

45 sort(l+1,l+1+cnt);

46for(int i=1;i<=cnt;i++)

47if(cntt==0||l[i]!=l[cntt])l[++cntt]=l[i];

48for(int i=1;i<=n;i++)

53write(ans);54}

55return0;

56 }

view code

珂朵莉的約數

珂朵莉給你乙個長為n的序列,有m次查詢 每次查詢給兩個數l,r 設s為區間 l,r 內所有數的乘積 求s的約數個數mod 1000000007 輸入描述 第一行兩個正整數n,m 第二行乙個長為n的序列 之後m行每行兩個數l和r 輸出描述 對於每個詢問,輸出乙個整數表示答案 示例1輸入 複製5564 ...

珂朵莉的值域連續段

珂朵莉的值域連續段 時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 題目描述 珂朵莉給你乙個有根樹,求有多少個子樹滿足其內部節點編號在值域上連續 一些數在值域上連續的意思即其在值域上構成乙個連續的區間 輸入描述 ...

校門外的樹 珂朵莉樹

題目描述 某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是11公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸00的位置,另一端在ll的位置 數軸上的每個整數點,即0,1,2,l0,1,2,l,都種有一棵樹。由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表...