題目大意:給出n個數,以及m個操作,每個操作分為兩種:
1 x y:將第x個數變為y
2 x y:判斷閉區間[x,y]中的數能否在進行公升序排序後構成一段連續且上公升序列
題目分析:因為涉及到了區間修改和區間查詢的問題,所以我們首先想到利用線段樹來輔助解決,第乙個操作很簡單,單點修改,主要是我們該怎麼樣在規定時間內完成第二個操作才是問題,這個題目的n和m給的都是5e5,那麼我們每次查詢最多只能以logn的複雜度查詢,就已經達到2e7的時間複雜度了,線段樹已經占用掉了logn的複雜度,所以留給我們的只能用o(1)的複雜度來判斷這個條件了。我想過能不能用歸併樹來實現這個題,應該不大行,畢竟是已經被淘汰了的資料結構,之前興致勃勃的用歸併樹做主席樹的題,很失望的t掉了555。說回這個題,我們需要知道乙個結論,就是從1~n異或出來的結果是有規律的,詳情請看我的上個部落格,有了這個就好判斷了,我們可以用線段樹維護乙個最小值,乙個區間和,乙個異或值,判斷的時候,我們可以通過最小值和區間長度判斷出最大值(因為數都是連續的,所以最小值加上區間長度就是最大值了。。),然後首先利用等差數列求和公式求一下這段的區間和應該是多少,再和線段樹中儲存的比較一下,如果相等再接著用異或的那個規律比較一下,這樣就能通過o(1)判斷是否滿足條件了。
對了有個細節需要注意一下,若求0~n區間異或的函式是xor_n(int n),那麼我們想求x~y區間內的異或,應該是xor_n(y)^xor_n(x-1)
而不是xor_n(y)-xor_n(x-1),想一想,為什麼?
好了直接上**了:
#include#include#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int n=5e5+100;
struct node
tree[n<<2];
void pushup(int k)
void build(int k,int l,int r)
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}void update(int k,int pos,int val)
int mid=tree[k].l+tree[k].r>>1;
if(mid>=pos)
update(k<<1,pos,val);
else
update(k<<1|1,pos,val);
pushup(k);
}int querymin(int k,int l,int r)
int queryxor(int k,int l,int r)
ll querysum(int k,int l,int r)
int xor_n(int n)
bool check(int len,int mmin,int xor_,ll sum)
int main()
}
return 0;
}
中石油訓練賽 招待 思維
題目大意 給出乙個天平,砝碼由3的冪次組成,再給出物品重量,求如何擺放砝碼能使得天平平衡 題目分析 既然給出的砝碼是3的冪次組成,那麼我們就將給出的物品重量轉換為三進製即可,那麼表示其每一位只有可能是0,1,2三個數字,我們假設物品擺在a盤,那麼 當前位數字為0,就說明該冪次沒有貢獻,所以不做處理 ...
中石油訓練賽 姓氏 思維 水題
在乙個很大的課室裡,裡面有很多學生在聽課。l老師挑選了其中的n個不同的學生起立回答問題,l老師對起立的每乙個學生都是問同樣的問題 在本課室裡,和你同姓的學生有多少人 不包括你自己 這n個起立的同學的回答如下 第1位起立的同學回答 和我同姓的,除了我之外,本課室裡還有a 1 個學生。第2位起立的同學回...
中石油訓練賽十 天平
莫名感覺這道題和找零錢是一樣一樣的,便於記憶情況下,還是給寫一下比較好 簡單思路 貪心,要使右盤所放砝碼最少,則要從較大質量的砝碼開始放起。小 t 到 cz 中學上的第一堂課是物理課,第一堂課 l 老師就把大家帶到創新實驗室去 做實驗了,實驗的內容是天平稱物。眾所周知天平是物理實驗室中的一種衡量物體...