題意 :
範圍: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 #includeview code3 #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 }
珂朵莉的約數
珂朵莉給你乙個長為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,都種有一棵樹。由於馬路上有一些區域要用來建地鐵。這些區域用它們在數軸上的起始點和終止點表...