原碼
原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值. 比如如果是8位二進位制:
其中,第一位為1是負數
[+1] = [0000 0001]原因此,8位二進位制數的取值範圍:[-127,127][-1] = [1000 0001]原
補碼正數的補碼是其本身
負數的補碼是在其原碼的基礎上,符號位不變,其餘各位取反,最後+1(即在其反碼的基礎上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]補反碼[-1] = [10000001]原 = [11111110]反 = [11111111]補
正數的反碼是其本身
負數的反碼是在其原碼的基礎上,符號位不變,其餘各個位取反
[+1] = [00000001]原 = [00000001]反技巧[-1] = [10000001]原 = [11111110]反
memset(a, 0x3f, sizeof(a))
給陣列賦值 0x3f3f3f3f
賦值正無窮 inf = 0x3f3f3f3f 或者 inf = 0x3f
移位運算
左移:n << x = n*2^x
右移:n >> x = n/2^x (在c++中右移為算數右移,即移出去的位丟棄,空缺位用「符號位」來填充)
快速冪原理解釋:
**模板:
int qmi(int m, int k, int p)
return res;
}
例題:
acwing 89. a^b
#includeusing namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int main()
cout
與快速冪原理相同,將乙個乘數分解成二進位制來表示,然後再相乘,防止溢位。
#includeusing namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int main()
cout例題
acwing 92. 遞迴實現指數型列舉
位運算解法:
#includeusing namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int main()
if (temp == 0) cout << " " << endl;
else cout << endl;
}return 0;
}
遞迴解法:
#includeusing namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
int n;
vectorres;
void solve(int x)
cout << endl;
return ;
}solve(x + 1);
res.push_back(x);
solve(x + 1);
res.pop_back();
}int main()
acwing 93. 遞迴實現組合型列舉
需要剪枝
#includeusing namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int m,n;
vectorres;
bool vis[30];
void solve(int cnt)
cout << endl;
return ;
}for (int i = 1; i <= n; i++)
}}int main()
acwing 94. 遞迴實現排列型列舉
在上一題的基礎上修改一部分**就行
#includeusing namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int n;
vectorres;
bool vis[30];
void solve(int cnt)
cout << endl;
return ;
}for (int i = 1; i <= n; i++)
}}int main()
acwing 99. 雷射炸彈
二維字首和
根據容斥原理,可以推導出二維字首和:s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]
#includeusing namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int sum[5050][5050];
int n,r;
int main()
for (int i = 1; i <= 5001; i++)
for (int j = 1; j <= 5001; j++)
sum[i][j] += sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1];//以(0,0)為左下角的矩形求二維字首和
int ans = 0;
for (int i = r; i <= 5001; i++)
for (int j = r; j <= 5001; j++)
ans = max(ans, sum[i][j] - sum[i][j-r] - sum[i-r][j] + sum[i-r][j-r]);//因為炸彈影響r*r矩形的範圍,根據容斥原理同樣可以推導出ans=sum[i][j]-sum[i][j-r]-sum[i-r][j]+sum[i][j],最後再取乙個最大值就行
cout << ans
簡單的差分題,注意去重
#includeusing namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int d[10005], res[10005];
set> vis;
int main()
)) continue;
vis.insert();
d[l + 1] --;
d[r] ++;
}res[0] = h;
for (int i = 1; i <= n; i++)
return 0;
}acwing 102. 最佳牛圍欄
二分出平均值,然後再用字首和找出該平均值條件下的最大子段和,在利用這個最大子段和來確定二分方向
#includeusing namespace std;
const int inf = 0x3f3f3f3f;
const double eps = 1e-5;
const int maxn = 1e6 + 50;
typedef long long ll;
int n, f;
double s[maxn], a[maxn], l, r, mid, ans, min_value;
int main()
if (ans >= 0) l = mid;
else r = mid;
}cout << (int)(r * 1000) << endl;
return 0;
}
演算法競賽高階指南學習筆記(2)
對頂棧 建立兩個棧 來動態維護序列中間的操作 類似對頂堆的思想 單調棧 棧內元素始終單調 排除不可能的選項 時間複雜度為o n 例題queue deque 單調佇列 單調佇列總不會寫 記得常練 cin n k for int i 1 i n i int head 1,tail 0 for int i...
《演算法競賽高階指南》 防曬
有c頭奶牛進行日光浴,第i頭奶牛需要minspf i 到maxspf i 單位強度之間的陽光。每頭奶牛在日光浴前必須塗防曬霜,防曬霜有l種,塗上第i種之後,身體接收到的陽光強度就會穩定為spf i 第i種防曬霜有cover i 瓶。求最多可以滿足多少頭奶牛進行日光浴。輸入格式 第一行輸入整數c和l。...
《演算法競賽高階指南》蚯蚓
蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去請神刀手來幫他們消滅蚯蚓。蛐蛐國裡現在共有 n 只蚯蚓,第 i 只蚯蚓的長度為 ai 所有蚯蚓的長度都是非負整數,即可能存在長度為0的蚯蚓。每一秒,神刀手會在所有的蚯蚓中,準確地找到最長的那乙隻,將其切成兩段。若有多隻最長的,則任...