題目背景
在人類智慧型的山巔,有著一台字長為10485761048576 位(此數字與解題無關)的超級計算機,著名理論計算機科
學家p博士正用它進行各種研究。不幸的是,這天颱風切斷了電力系統,超級計算機
無法工作,而 p 博士明天就要交實驗結果了,只好求助於學過oi的你. . . . . .
題目描述
p 博士將他的計算任務抽象為對乙個整數的操作。
具體來說,有乙個整數xx ,一開始為00 。
接下來有nn 個操作,每個操作都是以下兩種型別中的一種:
1 a b:將xx 加上整數a\cdot 2^ba⋅2
b,其中aa 為乙個整數,bb 為乙個非負整數
2 k :詢問xx 在用二進位制表示時,位權為2^k2
k的位的值(即這一位上的11 代表 2^k2k)
保證在任何時候,x\geqslant 0x⩾0 。
輸入的第一行包含四個正整數n,t_1,t_2,t_3n,t
1 ,t
2 ,t
3 ,nn 的含義見題目描述,t_1t
1 ,t_2t
2 ,t_3t
3 的具體含義見子任務。
接下來nn 行,每行給出乙個操作,具體格式和含義見題目描述。
同一行輸入的相鄰兩個元素之間,用恰好乙個空格隔開。
對於每個詢問操作,輸出一行,表示該詢問的答案(00 或11 )。對於加法操作,沒有任何輸出。
10 3 1 2
1 100 0
1 2333 0
1 -233 0
2 52 7
2 15
1 5 15
2 15
1 -1 12
2 1501
010在所有測試點中,1\leqslant t_1 \leqslant 3, 1 \leqslant t_2 \leqslant 4, 1 \leqslant t_3 \leqslant 21⩽t
1 ⩽3,1⩽t
2 ⩽4,1⩽t
3 ⩽2 。不同的 t_1, t_2, t_3t
1 ,t
2 ,t
3 對應的特殊限制如下:
對於 t_1 = 1t
1 =1 的測試點,滿足 a = 1a=1
對於 t_1 = 2t
1 =2 的測試點,滿足 |a| = 1∣a∣=1
對於 t_1 = 3t
1 =3 的測試點,滿足 |a| \leqslant 10^9∣a∣⩽10
9對於 t_2 = 1t
2 =1 的測試點,滿足 0 \leqslant b, k \leqslant 300⩽b,k⩽30
對於 t_2 = 2t
2 =2 的測試點,滿足 0 \leqslant b, k \leqslant 1000⩽b,k⩽100
對於 t_2 = 3t
2 =3 的測試點,滿足 0 \leqslant b, k \leqslant n0⩽b,k⩽n
對於 t_2 = 4t
2 =4 的測試點,滿足 0 \leqslant b, k \leqslant 30n0⩽b,k⩽30n
對於 t_3 = 1t
3 =1 的測試點,保證所有詢問操作都在所有修改操作之後
對於 t_3 = 2t
3 =2 的測試點,不保證詢問操作和修改操作的先後順序
本題共 25 個測試點,每個測試點 4 分。各個測試點的資料範圍如下:
先考慮暴力
我們將30位壓在一起,存到乙個陣列中,每次加減只要找到對應位置加上,處理進製即可
但這樣會t,因為進製可以是一整個陣列
什麼情況下會t呢?
考慮11111111111111111111111111111111111111......
我們加上乙個1
變成10000000000000000000000000000000000.....
又減去乙個1
變成1111111111111111111111111111111111111111.....
我們發現,如果進製的地方不是全1,可以直接加上
如果進製的地方全1,那麼重置為0,往下一位繼續進製
如果有一整段都為1,那麼全部置為0,往第乙個不全是1的位進1
所以可以寫乙個線段樹維護
【口胡很簡單。。。。。我不會說我調了乙個下午】
#include#include#include#define bit (1 << 30)
#define ls (u << 1)
#define rs (u << 1 | 1)
#define ll long long int
using namespace std;
const int maxn = 1000005,maxm = 1000005,inf = bit - 1;
inline ll read()
while (c >= 48 && c <= 57)
return out * flag;
}ll n,val[4 * maxn],tag[4 * maxn];
void pd(int u)
void upd(int u)
int modify(int u,int l,int r,int pos,ll v)
if (val[u] > inf)
return 0;
} pd(u);
int mid = l + r >> 1,t;
if (mid >= pos) t = modify(ls,l,mid,pos,v);
else t = modify(rs,mid + 1,r,pos,v);
upd(u);
return t;
}int add(int u,int l,int r,int pos)
return false;
} pd(u);
int mid = l + r >> 1,t = true;
if (l >= pos)
t = add(ls,l,mid,pos); upd(u);
return t;
} if (mid >= pos) t = add(ls,l,mid,pos);
if (t) t = add(rs,mid + 1,r,pos);
upd(u);
return t;
}int minus(int u,int l,int r,int pos)
return false;
} pd(u);
int mid = l + r >> 1,t = true;
if (l >= pos)
t = minus(ls,l,mid,pos); upd(u);
return t;
} if (mid >= pos) t = minus(ls,l,mid,pos);
if (t) t = minus(rs,mid + 1,r,pos);
upd(u);
return t;
}int getv(int u,int l,int r,int pos,ll v)
int main()
}else
} return 0;
}
線段樹 資料結構 NOIP2017列隊
很簡單的線段樹水題。不知道為啥一年前不會。每行開乙個線段樹,最後一列再開乙個線段樹。對每個操作分兩種情況討論 在最後一列,不在最後一列。如果不在最後一列,現在行線段樹上把那個位置刪去,在列線段樹末尾插入它。並且找到列線段樹對應的行的值,把他從列線段樹中刪除,加入到行線段樹中去。用動態加點的方式可以避...
NOIP2017模擬 鴨舌
題目 小美喜歡吃鴨舌。有乙個 n 個點的樹,每個節點 i 第 i 個點上有 ai 個鴨舌。小美一開始處於 x 號點。每次小美可以選擇乙個與現在的點有邊的點而且那個點還有鴨舌,那麼小美會走到那個點並吃乙個鴨舌。要保證小美最後還是走到 x 號點。問小美最多能吃幾個鴨舌?輸入格式 輸入第一行乙個整數 n ...
NOIP2017模擬 區間
2017.11.3 t1 2032 樣例資料 輸入3 2 1 2 1 1 2 4 5輸出 2 6分析 這道題為什麼要放在t1 考得我懷疑人生。本來也只會暴力找,對於30 的資料我是這樣的 先離散化,再二維陣列記錄所有顏色的在每個位置的字首和,然後四層迴圈暴力查詢。而正解是 先離散化,再把每種顏色的每...