題目大意:先輸入n,然後儲存這n個數字,然後輸入m,表示m次操作。有兩種操作,第一種是儲存輸入的乙個數字,第二種是輸入乙個數字,找儲存的數字和這個數字異或和最大的數字,輸出這個儲存的數字。(n,m<=100000 輸入的數字<=1000000)
前言:講這道題前先**一下字典樹。如果有n個小寫字母,然後有m個查詢,每個查詢包含乙個字母,問這個字母在n個字母中出現幾次,怎樣高效的查詢?
1.for找n遍,複雜度o(n*m)
2.vis[c-'a']++,hash表存字母出現的個數,複雜度o(m)
換乙個問題,如果有n個字串,然後有m個查詢,每個查詢包含乙個字串,問這個字串在n個字串中出現幾次,怎樣高效的查詢?
0.for 迴圈。
1.用map ,插入複雜度o(logn),查詢複雜度o(mlogn) ,map找字串是否匹配還要乙個個去比較字元是否相等
2.類似上面的第二個方法,用hash表去找,但是要找一遍單詞的每個字元是否在hash表裡,相當於多次進行第乙個問題的操作。複雜度明顯比map低很多。所以問題就在於怎麼去找,在第乙個字元一樣的前提,怎麼去找下乙個字元。
什麼時候用到字典樹?查詢的物件需要依次進行hash查詢的時候。
比如:給定n個單詞,查詢n個單詞中字首為"abc"的是否存在,用hash去找a是否存在,a存在的話去找b,在去找c,這就是多次去找。字首abc第一次去找a,找到後去x位置找b,而如果字首是"cbb"的話,第一次找c,然後從y位置去找b,x和y的位置必然是不同,因為位置相同的話表示他們兩個之前找的字元必然完全相同。這就是上一次的查詢結果會影響到下次。
下面給出這道題的思路:
一般演算法複雜度o(n*m) 在這裡不贅述。下面講ac解法。
要求出異或後的值最大,異或表示相同為0,不同為1。什麼情況下值會最大?越高位出現0^1,則值越大。所以說把查詢的值轉成二進位制,從高位開始,如果查詢的數是0,則所有被查詢的高位有沒有1,是1則找0。然後在找下一位。有沒有想到什麼?這不就是字典樹的本質:查詢的物件需要依次進行多次的hash查詢。
下面給出**:
#include #include #include using namespace std;
struct node
tree[(1<<22)+10];
int sum,bit[20];
void create(int num)
else
bit[j]=0;
}else
else}}
tree[pos].id=num;
return ;
}int main(int argc, char *argv)
create(tnum);
}cin>>m;
while(m--)
if(op)
else
}else
else
bit[i]=0;}}
printf("%d\n",tree[pos].id);
}else}}
return 0;
}
careercup 中等難度 17 8
17.8 給定乙個整數陣列 有正數和負數 找出總和最大的連續序列,並返回總和。解法 就是求連續子串行的和最大,不過存在乙個問題 假設整個陣列都是負數,怎麼樣才是正確的行為呢?看看這個簡單的陣列,一下答案每個都可以說的通 3 假設子串行不能為空 0 子串行的長度為空 int min 視為錯誤的情況 我...
178 分數排名
編寫乙個 sql 查詢來實現分數排名。如果兩個分數相同,則兩個分數排名 rank 相同。請注意,平分後的下乙個名次應該是下乙個連續的整數值。換句話說,名次之間不應該有 間隔 例如,根據上述給定的 scores 表,你的查詢應該返回 按分數從高到低排列 例如,根據上述給定的 scores 表,你的查詢...
178 分數排名
編寫乙個 sql 查詢來實現分數排名。如果兩個分數相同,則兩個分數排名 rank 相同。請注意,平分後的下乙個名次應該是下乙個連續的整數值。換句話說,名次之間不應該有 間隔 id score 1 3.50 2 3.65 3 4.00 4 3.85 5 4.00 6 3.65 例如,根據上述給定的 s...