Yeedrag
(你要用線段樹我也沒意見)
1 | 5 | 3 | 7 | 6 |
---|
1 | 6 | 9 | 16 | 22 |
---|
arr
pre
查詢[a,b]的和: pre[b]-pre[a-1]
1 | 3 | 7 |
---|---|---|
4 | 2 | 8 |
1 | 1 | 5 |
1 | 4 | 11 |
---|---|---|
5 | 10 | 25 |
6 | 12 | 32 |
arr
pre
sum[a~b][c~d] = pre[b][d] - pre[a-1][d] - pre[b][c-1] + pre[a-1][c-1]
k筆要求,在第c格加val?
提示:怎麼設計前綴和來做到要的結果呢?
c | 0 | 0 | -c | 0 |
---|
arr
c | c | c | 0 | 0 |
---|
pre
在[1,3]加上c的例子
#include<bits/stdc++.h>
#define debug(x) cerr<<#x<<" = "<<(x)<<endl;
using namespace std;
int main(){
int k = 1<<2;//左移兩次
cout<<k<<endl;//4
int v = 13>>1//右移一次
cout<<v<<endl;//6
}
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<(5&3)<<endl;//1
cout<<(7&4)<<endl;//4
}
bruh他歪七扭八ㄉ
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<(5|3)<<endl;//7
cout<<(7|4)<<endl;//7
}
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<(5^3)<<endl;//6
cout<<(7^4)<<endl;//3
}
提示點我
a ^ a = 0
btw codeforces超愛考位元ㄉ
這題好玩
#include<bits/stdc++.h>
using namespace std;
int pow(int a,int n){
int sum = 1;
for(int i=0;i<n;i++) sum*=a;
return sum;
}
int main(){
cout<<pow(3,5)<<endl;//243
}
複雜度: \(O(N)\)
(如果\(n\)是奇數要多乘\(a\))
#include<bits/stdc++.h>
using namespace std;
long long fastpow(int a,int n){
if(n==0) return 1;//a^0 = 1
int half = fastpow(a,n/2);//算出 a^(b/2)
if(n&1){//n是奇數
return half*half*a;
} else {
return half*half;
}
}
int main(){
cout<<fastpow(3,15)<<endl;//14348907
}
當然也可以寫成迴圈式,而且會快一點點
#include<bits/stdc++.h>
using namespace std;
int mod = (int)1e9+7;
long long fastpow(int a,int n){
if(n==0) return 1;//a^0 = 1
//a%=mod;
int half = fastpow(a,n/2);//算出 a^(b/2)
if(n&1){//n是奇數
return ((half*half)%mod*a)%mod;
} else {
return (half*half)%mod;
}
}
int main(){
cout<<fastpow(3,13)<<endl;//1594323
}
簡單來說就是前後都可以操作!
push_back/front 添加元素到尾/頭
pop_back/front 移除尾/頭元素
insert 插入元素
erase 移除元素
clear 清空容器
empty 回傳是否是空的
size 回傳目前長度
跟別的stl用法差不多就不放扣了 .w.
注意這題k有可能大於n
以下以找滑窗最大為例(最小也差不多la)
我們想要做一個前面最大、且是單調遞減的隊列
前面彈出條件: 超出隊列
後面彈出條件: 不可能為答案 (新進來的比他還大,以後不可能有機會是他最大)
1 | 3 | -1 | -3 | 5 | 3 | 6 | 7 |
---|
n = 8, k = 3
i =
0
1
2
3
4
5
6
7
0
1
2
3
4
5
6
7
3
3
5
5
6
7
slides做動畫好難;-;
#include<bits/stdc++.h>
#pragma GCC optimize("O3")
#define guracute ios_base::sync_with_stdio(false); cin.tie(0)
using namespace std;
void solve(){
int n,k;
while(cin>>n>>k){
deque<int> mono_dq;//單調隊列
vector<int> vec(n);//原陣列
for(auto &i:vec) cin>>i;
k = min(n,k);//此題k有可能>n
//最小
for(int i=0;i<n;i++){
//對於最小,保持隊列最前最小
//要注意一定要檢查隊列裡是否有東西不然會RE
while(mono_dq.size()&&mono_dq.front()<=i-k){
//如果目前隊列最前面的已經出滑窗了
mono_dq.pop_front();
}
while(mono_dq.size()&&vec[mono_dq.back()]>vec[i]){
//從後面把不可能的開始刪除
mono_dq.pop_back();
}
mono_dq.push_back(i);//目前數字放入隊列
if(i==k-1) cout<<vec[mono_dq.front()];
//到k-1時才正式包進第一次滑窗
if(i>k-1) cout<<" "<<vec[mono_dq.front()];
}
cout<<endl;
mono_dq.clear();
//最大
for(int i=0;i<n;i++){
while(mono_dq.size()&&mono_dq.front()<=i-k){
mono_dq.pop_front();
}
while(mono_dq.size()&&vec[mono_dq.back()]<vec[i]){
mono_dq.pop_back();
}
mono_dq.push_back(i);
if(i==k-1) cout<<vec[mono_dq.front()];
if(i>k-1) cout<<" "<<vec[mono_dq.front()];
}
cout<<endl;
}
return;
}
signed main(){
guracute;
int cases = 1;
//cin>>cases;
while(cases--) solve();
return 0;
}
Code:
(可以用單調stack)