lmx
(i,j
)' role="presentation" style="position: relative">mx(
i,j)
mx(i
,j)表示第i+
1' role="presentation" style="position: relative">i+1
i+1塊左端點到點
j' role="presentation" style="position: relative">j
j區間中最大的兩個數的異或值,顯然這個可以用乙個trie很快地做出來,時間複雜度為o(
31⋅nn
)' role="presentation" style="position: relative">o(31
⋅nn−
−√)o
(31⋅n
n)。接著對於每乙個詢問,如果這個詢問的左右端點在同一塊內,直接用trie暴力算出結果即可,時間複雜度為o(
31n)' role="presentation" style="position: relative">o(31
n−−√
)o(31
n)。否則,這個區間就會被左端點所在塊的右邊界分割成兩段,其中右邊那段可以直接用前面算出的mx
' role="presentation" style="position: relative">mxm
x進行o(
1)' role="presentation" style="position: relative">o(1
)o(1
)計算,而左邊那段可以直接暴力o(
31n)' role="presentation" style="position: relative">o(31
n−−√
)o(31
n)進行計算,關鍵是如何求出乙個數在左邊,乙個數在右邊的最大異或值呢?只需要對整個序列建乙個可持久化trie,然後對於左邊的每乙個點,在可持久化trie對應的區間中貪心即可,時間複雜度為o(
31n)' role="presentation" style="position: relative">o(31
n−−√
)o(31
n)。 於是我們就以o(
31⋅nn
)' role="presentation" style="position: relative">o(31
⋅nn−
−√)o
(31⋅n
n)的時間複雜度完成了這一題。
以下是本人**:
#include
using
namespace
std;
typedef
long
long ll;
int n,m,blocksiz,a[12010],pre[12010],suf[12010],block[12010],totp,tot;
int rt[12010]=,nowrt[12010]=,mx[120][12010]=;
int sum[400010]=,ch[400010][2]=;
void insert(int v,int last,int x,bool mode)
}int query(int v,int last,int x)
return ans;
}void init()
}for(int i=1;i<=n;i++)
}int solve(int l,int r)
}else
}return ans;
}int main()
suf[n+1]=0;
for(int i=n;i>=1;i--)
suf[i]=suf[i+1]^a[i];
init();
int lastans=0;
for(int i=1;i<=m;i++)
return
0;}
bzoj2741 分塊 可持久化Trie
題意中文我就不說了 解析 分塊 可持久化trie,先得到字首異或值,插入到trie中,然後分塊,對每一塊,處理出dp i j i代表第幾塊,j代表第幾個位置 dp i j 代表以第i塊開始的到j這個位置 的連續字串最大異或值。查詢時,如果l,r不在同一塊內,可以先查詢l所在的塊的後乙個塊到r的連續字...
bzoj 3166 可持久化Tire
每乙個數能做出的貢獻就是其兩端第二個比他大的中間的數和他的異或值 按權值大小排序,按照位置扔進set,set內的元素都是比他大的,也是全的 然後tire上跑就行了。include include include include include include define n 50050 using...
BZOJ 3166 可持久化Trie
welcome to alo arithmetic and logistic online 這是乙個vr mmorpg 如名字所見,到處充滿了數學的謎題。現在你擁有n顆寶石,每顆寶石有乙個能量密度,記為ai,這些寶石的能量 密度兩兩不同。現在你可以選取連續的一些寶石 必須多於乙個 進行融合,設為 a...