CSU_1216(異或最大值)
題目簡述:
經典題目,求一個數組中兩個數異或運算的最大值。題目極其簡單,但是要求的複雜度需要達到O(N * log(N)),還是比較難的。
解題思路:
總的思路就是構建一棵0-1字典樹,然後一個數讓查詢一個與其異或結果最大的數的效率達到O(log(N)),這裡因為異或的特殊性質,可以使用貪心法則來實現。
1、0-1字典樹:
這裡其實是就是二叉樹,之所以叫做字典樹是因為我們的演算法把一個數當成了一個31位的字串來看,比如1就是三十個零外加一個一,這一部分還是比較簡單的。
2、貪心找最大異或值:
異或運算有一個性質,就是對應位不一樣為1,我們要讓結果最大化,就要讓越高的位置為1。我們找跟一個數的異或結果最大的數,就從樹的根結點(最高位)開始找,如果對應位置這個數是0,優先去找那一位為1的數,找不到才去找0;如果對應位置這個數是1,優先去找那一位為0的數,找不到才去找0;最終找到的數就是跟這個數異或結果最大的數。n個數,每個數找一個這樣的數並算出結果求其中的最大值,可以得到答案。
程式碼:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,a[100005],tmp[35];
struct node{
int val;
node *left, *right;
node(int value=-1){
val = value;
left = right = NULL;
}
};
node *head = NULL;
void cal(int num){
memset(tmp,0,sizeof(tmp));
int cnt=0;
while(num){
tmp[cnt++]=num%2;
num/=2;
}
for(int i=0;i<15;i++)
swap(tmp[i],tmp[30-i]);
}
void insert(node* &head, int index, int &num){
if(index+1==31){
head->val = num;
return;
}
if (tmp[index+1]==0 && !head->left)
head->left = new node(-1);
if(tmp[index+1]==1 && !head->right)
head->right = new node(-1);
if(tmp[index+1]==0)
insert(head->left,index+1,num);
if(tmp[index+1]==1)
insert(head->right,index+1,num);
}
int dfs(node* &head,int index){
if(index+1==31)
return head->val;
if(tmp[index+1]==0){
if(head->right){
return dfs(head->right,index+1);
}else{
return dfs(head->left,index+1);
}
}else{
if(head->left){
return dfs(head->left,index+1);
}else{
return dfs(head->right,index+1);
}
}
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
head = new node(-1);
for(int i=0;i<n;i++)
{
cal(a[i]);
insert(head,-1,a[i]);
}
int ans=0;
for(int i=0;i<n;i++)
{
cal(a[i]);
ans = max(ans, a[i]^dfs(head,-1));
}
printf("%d\n",ans);
}
return 0;
}
總結:
簡單的資料結構用得好可以做很多很奇妙的事情,貪心不能忘啊!
相關推薦
CSU_1216(異或最大值)
題目簡述: 經典題目,求一個數組中兩個數異或運算的最大值。題目極其簡單,但是要求的複雜度需要達到O(N * log(N)),還是比較難的。 解題思路: 總的思路就是構建一棵0-1字典樹,然後一個數讓查詢一個與其異或結果最大的數的效率達到O(log(N)
01字典樹專題 (解決異或最大值問題)不斷更新ing~
以前一直以為字典樹沒有多少用,但是最近一直碰到(難道是以前刷題太少的原因麼),其中有一類問題叫做01字典樹問題,它是用來解決xor的有力武器,通常是給你一個數組,問你一段連續的異或和最大是多少,正常思路貪心dp啥的都會一頭霧水,但是用01字典樹就能很快的解決,實現起來也十分
異或最大值(01字典樹)
#include<bits/stdc++.h> using namespace std; const int maxn = 100000 + 5; //集合中的數字個數 typedef long long LL; int ch[32 * maxn
Chip Factory (字典樹求異或最大值)
John is a manager of a CPU chip factory, the factory produces lots of chips everyday. To manage large amounts of products, every processor
Chip Factory(01字典樹求異或最大值)
題目描述 John is a manager of a CPU chip factory, the factory produces lots of chips everyday. To manage large amounts of products, every p
[二進制trie][貪心]CSUOJ1216異或最大值
include 貪心 targe printf IV 左右 class using ace 題目傳送門 過了好久,終於重新開始寫博客了。。。 這是一道二進制trie樹的模板題。 二進制trie樹,理解一下就是一顆二叉樹,左右兒子為0或1。 然後每插入一個數就進行一次
異或最大值
pre tmp 數字 markdown %d getchar using 整數 getch 1、1216: 異或最大值 http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1216 Time Limit: 2 Sec Me
中國石油大學 Chip Factory(字典樹處理異或最大值)
9264: Chip Factory 時間限制: 5 Sec 記憶體限制: 128 MB 提交: 268 解決: 61 [提交] [狀態] [討論版] [命題人:admin] 題目描述 John is a manager of a CPU chip factory,
MQTT的Payload(負載的最大值)是多少?
我們在學習使用MQTT協議的時候,有的時候我們需要通過MQTT進行一些二進位制的傳送,那麼請問MQTT進行二進位制的傳送的時候,最大支援多少個位元組? 網上答案五花八門,有說64kb的,有說16kb的,有說256kb,有說256M的, 那麼到底是多少呢? 其實答案很簡單,就是268
中國石油大學 Chip Factory(字典樹處理異或最大值)
9264: Chip Factory 時間限制: 5 Sec 記憶體限制: 128 MB 提交: 268 解決: 61 [提交] [狀態] [討論版] [命題人:admin] 題目描述 John is a
[cqbzoj]區間異或最大值
奶牛異或 時間限制: 1 Sec 記憶體限制: 64 MB 題目描述 農民約翰在餵奶牛的時候被另一個問題卡住了。他的所有N(1 <= N <= 100,000)個奶牛在他面前排成一行(按序號1..N的順序),按照它們的社會等級排序。奶牛#
二進位制trie樹解異或最大值問題
trie樹一般可以用於查詢與指定值最近的,而二進位制trie樹因為每個節點最多有兩個子節點,所以也可以查詢與指定值最遠的值,即異或最大值。 (1)問題:給定一個數組,在陣列中找到兩個數,使得這兩個數的異或值最大 (2)要點:對於陣列中的每個元素,二進位制trie樹查詢異
Codeforces 811C Vladik and Memorable Trip (區間異或最大值)【線性DP】
所有 一個 true sin %d 如果 不同 esp ace <題目鏈接> 題目大意: 給你n個數,現在讓你選一些區間出來,對於每個區間中的每一種數,全部都只能出現在這個區間。 每個區間的價值為該區間不同的數的異或值之和,現在問你這n個數最大的價值是多少。
RMQ——蒜頭君的玩具娃娃(區間範圍最大值-區間範圍最小值)
mes default bsp lose 格式 baseline 自己的 con using 蒜頭君有 N 個玩具娃娃,編號依次從 1 到 N,每個娃娃都有自己的高度值。蒜頭君想考考聰明的你,蒜頭君會有 Q 次詢問,每次詢問給定兩個整數 A 和 B,求問編號 A 和編號
POJ-2456 Aggressive cows---最大化最小值(也就是求最大值)
思路 cst target main include IT urn cstring strong 題目鏈接: https://vjudge.net/problem/POJ-2456 題目大意: 有n個牛欄,選m個放進牛,相當於一條線段上有 n 個點,選取 m 個點, 使得相
單調隊列 —— 滑動窗口(滾動最大值)
簡單 保持 工作 影響 區間最值 因此 for 開始 += 一道經典的單調隊列題目——[洛谷P1886 滑動窗口]。(下文開始只討論求滾動的最大值) 暴力解法是O(n^2)的,對於每一個起點,搜一遍長度為k的子序列,求得最值—&mdas
算法學習——貪心算法之刪數字(求最大值)
size 算法學習 末尾 最小 條件 求最大值 sca 位數 技術 算法描述 在給定的n位數字,刪除其中的k位數字( k < n),使得最後的n-k為數字為最大值(原次序不變) 算法思路 考慮到是要移出數字,我們使用鏈表設計此算法較為方便,鏈表可以直接移出某個位
kuangbin專題七 HDU1754 I Hate It (單點修改維護最大值)
cond color include 專題 一次 span 修改 信息 \n 很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。 這讓很多學生很反感。 不管你喜不喜歡,現在需要你做的是,就是按照老師的要求,寫一個程序,模擬老師的
NOIP2015day2 運輸計劃(二分答案+差分/抽路+字首最大值)
題意 https://www.luogu.org/problemnew/show/P2680 思路 最大路徑最短,二分吧。。。然後就二分了,考試時 95
04 -pandas索引的堆(行列操作,交換行列)、聚合操作(求和、最大值、最小值、平均值等)
引入模組 import pandas as pd from pandas import Series,DataFrame import matplotlib.pyplot as plt 建立示例DataFrame # 用作案例 不要刪 !!! data=np.random.ra