---
# System prepended metadata

title: OAI

---

# OAI
::: spoiler **Mục lục**
[TOC]
:::
## IMPLEMENTATION
### I. Implementation Fundamentals
[I. Implementation Fundamentals](https://hackmd.io/8mi7YiLsQ1GC3RWtXYbS4A)
### II. Implementation (Đề hỏi gì làm nấy)
::::spoiler **1. Bitmask**
**1.1. IsZero(x)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool IsZero(int x){
    return !(x&(-x));
}
int main(){
    int n;
    cin>>n;
    cout<<(IsZero(n)?"YES":"NO");
    return 0;
}
```
:::
==Giải thích  :== Kiểm tra n có phải là số không không. Nếu có thì xuất "YES", không thì xuất "NO".

---

**1.2. IsOdd(X), IsEven(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool IsOdd(int x){
    return x&1;
}
bool IsEven(int x){
    return !(x&1);
}
int main(){
    int a,b;
    cin>>a>>b;
    cout<<(IsOdd(a)?"YES":"NO");
    cout<<(IsEven(b)?"YES":"NO");
    return 0;
}
```
:::
==Giải thích  :== Kiểm tra a có phải số lẻ và b có phải số chẵn không. Nếu có xuất "YES", không thì xuất "NO"

---

**1.3. IsPowerOfTwo(x)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool IsPowerOfTwo(long long x){
    return (x>0&&(x&(x-1))==0)   ; 
}
int main(){
    long long n;
    cin>>n;
    cout<<(IsPowerOfTwo(n)?"YES":"NO");
    return 0;
}
```
:::
==Giải thích  :== Kiểm tra n có phải là lũy thừa của hai không

---

**1.4. IsPowerOfFour(X), IsPowerOfPowerOfTwo(X, K)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool IsPowerOfFour(long long x){
    return (x>0&&(x&(x-1))==0)&&(x & 0x55555555));
}
bool IsPowerOfPowerOfTwo(long long x,long long k){
    if(x<=0||k<=0||x&(x-1)!=0) return false;
    int cnt=0;
    while(x){
        x>>=1;
        cnt++;
    }
    return (cnt%k==0);
}
int main(){
    long long n;
    cin>>n;
    cout<<(IsPowerOfFour(n)?"YES":"NO");
    long long x,y;
    cin>>x>>y;
    cout<<(IsPowerOfPowerOfTwo(x,y)?"YES":"NO");
    return 0;
}
```
:::
==Giải thích:== 
-Hàm IsPowerOfFour(x) được dùng để kiểm tra xem x có phải là lũy thừa của bốn không.
-Hàm IsPowerOfPowerOfTwo(x,k) được dùng để kiểm tra xem liệu có tồn tại một số p sao cho x= 2^p*k^.

---

**1.5. CheckBit(X, B) SetBit(X, B) UnsetBit(X, B) ToggleBit(X, B)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;

bool CheckBit(long long x,long long b){
    return ((x>>b)&1);
}

void SetBit(long long x,long long b){
    return (x|(1<<b));
}

void UnsetBit(long long x,long long b){
    return x&~(1<<b);
}

void ToggleBit(long long x,long long b){
    return x^(1<<b);
}

int main(){
    int n,b;
    cin>>n>>b;
    cout<<(CheckBit(n,b)?"YES":"NO");
    SetBit(x,b);
    cout<<x;
    UnsetBit(x,b);
    cout<<x;
    ToggleBit(x,b);
    ToggleBit(x,b-1);
    cout<<x;
    return 0;
}
```
:::
==Giải thích:==
-Hàm CheckbBit(x,b): kiểm tra vị trí bit thứ b của số nguyên x đã được bật chưa.
-Hàm SetBit(x,b): Bật bit thứ b của số nguyên x.
-Hàm UnsetBit(x,b): Tắt bit thứ b của số nguyên x.
-Hàm ToggleBit(x,b): Thay đổi giá trị của bit thứ b của số nguyên x.

---

**1.6.AssignBit(X, B, V)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
void AssignBit(long long x,long long b,long long v){
    if(v) return x|(1<<b);
    return x&~(1<<b);
}
int main(){
    int n,b,v;
    cin>>n>>b>>v;
    AssignBit(n,b,v);
    cout<<n;
    return 0;
}
```
:::
==Giải thích:==
- Hàm AssignBit(x,b,v): gán giá trị (1 hoặc 0) cho bit thứ b của số nguyên x.

---

**1.7. ToBinary(X), ToOctet(X), ToHex(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
#include <bitset>
#include <algorithm>
using namespace std;
void ToBinary(long long& x){
    bitset<32> bs(x);
    cout<<bs;
}
string ToOctet(long long x){
    if (x == 0) return "0";
    string octal = "";
    while (x > 0) {
        octal += to_string(x % 8);
        x /= 8;
    }
    reverse(octal.begin(), octal.end());
    return octal;
}
string ToHex(long long x) {
    if (x == 0) return "0";
    string hexChars = "0123456789ABCDEF", hex;
    while (num > 0) {
        hex += hexChars[x % 16];
        x /= 16;
    }
    reverse(hex.begin(), hex.end());
    return hex;
}
int main(){
    long long n;
    cin>>n;
    ToBinary(n);
    string result;
    result=ToOctet(n);
    cout<<result;
    result=ToHex(n);
    cout<<result;
    return 0;
}
```
:::
==Giải thích:==
-Hàm ToBinary(x): chuyển số nguyên x thành số nhị phân.
-Hàm ToOctet(x): chuyển số nguyên x thành số bát phân.
-Hàm ToHex(x): chuyển số nguyên x thành số thập lục phân.

---
**1.8. FullMask(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
#include <cstdint>
using namespace std;
inline uint64_t FullMask(long long x) {
    if (x == 64) {
        return ~uint64_t;
    }
    return ((uint64_t)1 << x) - 1;
}
int main(){
    int n,m;
    cin>>n>>m;
    XorSwap(n,m);
    cout<<n<<" "<<m;
    return 0;
}
```
:::
==Giải thích:== 
-Hàm XorSwap(x,y): đổi giá trị của hai số bằng xor.

---
**1.9. XorSwap(X,Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
void XorSwap(long long& x,long long& y){
    x^=y;
    y^=x;
    x^=y;
}
int main(){
    int n,m;
    cin>>n>>m;
    XorSwap(n,m);
    cout<<n<<" "<<m;
    return 0;
}
```
:::
==Giải thích:== 
-Hàm XorSwap(x,y): đổi giá trị của hai số bằng xor.

---
**1.10. BitLength(X), Log2(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
int BitLength(long long x) {
    if(x==0)return 0;
    int cnt = 0;
    while(x>0) {
        x>>=1;
        cnt++;
    }
    return cnt;
}
long long Log2(long long x){
    long long cnt=0;
    while(x){
        x>>=1;
        cnt++;
    }
    return cnt-1;
}

int main() {
    long long x; cin >> x;
    cout<<BitLength(x)<<"\n";
    cout<<Log2(x);
    return 0;
}
```
:::
==Giải thích:== 
-Hàm BitLength(x): tính độ dài bit của số X (số bit cần thiết để thể hiện số X).
-Hàm Log2(x): trả về giá trị log~2~x.

---

**1.11.CountSetBit(X), CountUnsetBit(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
#include <bitset>
using namespace std;
long long CountSetBit(long long x){
    long long cnt=0;
    while(x){
        cnt+=x&1;
        x>>=1;
    }
    return cnt;
}
long long CountUnsetBit(long long x){
    return 16-CountSetBit(x);
}
int main(){
    long long x;
    cin>>x;
    cout<<CountSetBit(x)<<'\n'<<CountUnsetBit(x);
    return 0;
}
```
==Giải thích:==
-Hàm CountSetBit(x): Đếm số bit đã được bật của số nguyên x.
-Hàm CountUnsetBit(x): Đếm số bit chưa được bật của số nguyên x.

---

**1.12.CountTrailingZero(X), CountTrailingOne(X)**
```cpp=
#include <isotream>
using namespace std;
long long CountTrailingZero(long long x){
    if(!(x)) return 16;
    long long cnt=0;
    while(!(x&1)){
        cnt++;
        x>>=1;
    }
    return cnt;
}
long long CountTrailingOne(long long x){
    long long cnt=0;
    while((x&1)){
        cnt++;
        x>>=1;
    }
    return cnt;
}
int main(){
    long long x;
    cin>>x;
    cout<<CountTrailingZero(x)<<'\n'<<CountTrailingOne(x);
    return 0; 
}
```
:::
==Giải thích:== 
-Hàm CountTrailingZero(x): trả về số lượng chuỗi chữ số 0 ở cuối.
-Hàm CountTrailingOne(x): trả về số lượng chuỗi chữ số 1 nối nhau ở cuối.

---

**1.13.CountLeadingZero(X), CountLeadingOne(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
int BitLength(long long x) {
    if(x==0)return 16;
    int cnt=0;
    while(x>0) {
        x>>=1;
        cnt++;
    }
    return cnt;
}
long long CountLeadingZero(long long x){
    return 16-BitLength(x);   
}
long long CountLeadingOne(long long x){
    long long cnt=0;
    for(int i=16;i>=0;--i){
        if(!((x>>i)&1)) break;
        cnt++;
    }
    return cnt;
}
int main(){
    long long n;
    cin>>n;
    cout<<CountLeadingZero(n)<<'\n'<<CountLeadingOne(n);
    return 0;
}
```
:::
==Giải thích:==
-Hàm CountLeadingZero(x): Trả về số lượng chuỗi chữ số 0 ở đầu.
-Hàm CountLeadingOne(x): Trả về số lượng chuỗi chữ số 1 ở đầu.

---

**1.14.LeastSignificantBit(X), MostSignificantBit(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
// idk,idu ;-; ?
```
:::

==Giải thích:== 
-Hàm LeastSignificantBit(X):
-Hàm MostSignificantBit(X):

---
**1.15.BitLeftRotation(X, N), BitRightRotation(X, N)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long BitLeftRotation(long long x,long long n){
    return (x<<n)|(x>>(32-n));
}
long long BitRightRotation(long long x,long long n){
    return (x>>n)|(x<<(32-n));
}
int main(){
    long long x,n;
    cin>>x>>n;
    long long x1,n1;
    cin>>x1>>n1;
    cout<<BitLeftRotation(x,n)<<'\n'<<BitRightRotation(x1,n1);
    return 0;
}
```
:::

==Giải thích:== 
-Hàm BitLeftRotation(x,n): Đẩy bit, của số nguyên x, sang trái n bit.
-Hàm BitRightRotation(x,n): Đẩy bit, của số nguyên x, sang phải n bit. 

---
**1.16.SubmaskEnumeration(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
void SubmaskEnumeration(long long x){
    for(long long i=x;i;i=(i-1)&x){
        cout<<i<<'\n';
    }
}
int main(){
    long long n;
    cin>>n;
    SubmaskEnumeration(n);
    return 0;
}
```
:::

==Giải thích:== 
-Hàm SubmaskEnumeration(x): Liệt kê các submask của x.

---
**1.17.SignOf(X), IsPositive(X), IsNegative(X), HasOppositeSign(X, Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
char SignOf(long long x){
    if((x>0)-(x<0)) return '+';
    else if(!((x>0)-(x<0))) return '-';
    return '0';
}
bool IsPositive(long long x){
    return (x>0);
}
bool IsNegative(long long x){
    return (x<0);
}
bool HasOppositeSign(long long x,long long y){
    return ((x^y)<0);
}
int main(){
    long long a,b;
    cin>>a>>b;
    cout<<SignOf(a)<<'\n'<<IsPositive(a)<<'\n'<<IsNegative(b)<<'\n'<<HasOppositeSign(a,b);
    return 0;
}
```
:::

==Giải thích:== 
-Hàm SignOf(x): Kiểm tra dấu của x.
-Hàm IsPositive(x): Kiểm tra xem x có dương không.
-Hàm IsNegative(x): Kiểm tra xem x có âm không.
-Hàm HasOppositeSign(x,y): Kiểm tra x và y có trái dấu nhau không.

---
**1.18.IsolateLowestSetBit(X), ClearLowestSetBit(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long IsolateLowestSetBit(long long x){
    return x&-x;
}
long long ClearLowestSetBit(long long x){
    return x&(x-1);
}
int main(){
    int n;
    cin>>n;
    cout<<IsolateLowestSetBit(x)<<'\n'<<ClearLowestSetBit(x);
    return 0;
}
```
:::

==Giải thích:== 
-Hàm IsolateLowestSetBit(x): trả về dãy bit chỉ có bit đã được bật tại vị trí thấp nhất của x.
-Hàm ClearLowestSetBit(x): xóa bit được bật tại vị trí thấp nhất của x.

---
**1.19.BitAbs(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
long long BitAbs(long long x) {
    const long long bits=sizeof(long long)*8;
    long long mask=x>>(bits-1);
    return (x^mask)-mask;
}
int main() {
    long long x; cin>>x;
    cout<<BitAbs(x);
}
```
:::
==Giải thích:==
- Hàm BitAbs(): Trả về giá trị tuyệt đối của số thông qua bit.

---

**1.20.BitMin(X, Y), BitMax(X, Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;

long long BitMin(long long x,long long y){
    return y^((x^y)&-(x<y));
p                                                           ppppppppppppppppp                         }
long long BitMax(long long x,long long y){
    return x^((x^y)&-(x<y));
}

int main(){
    long long x,y,a,b;
    cin>>x>>y>>a>>b;
    cout<<BitMin(x,y)<<'\n'<<BitMax(a,b);
    return 0;
}
```
:::
==Giải thích:== 
-Hàm BitMin(X,Y): tìm số nhỏ nhất giữa hai số bằng bit.
-Hàm BitMax(X,Y): tìm số lớn nhất giữa hai số bằng bit.

---

**1.21.LexicoNextBitPermutation(X), LexicoPrevBitPermutation(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long 
int main(){
    
}
```
:::
-Hàm LexicoNextBitPermutation(X): idk
-Hàm LexicoPrevBitPermutation(X): idk

---
**1.22.NextPowerOfTwo(X), PrevPowerOfTwo(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <isotream>
using namespace std;
long long NextPowerOfTwo(long long x){
    if(!(x)) return 1;
    x--;
    x|=x>>1;
    x|=x>>2;
    x|=x>>4;
    x|=x>>8;
    x|=x>>16;
    return x+1;
}
long long PrevPowerOfTwo(long long x){
    if(x==0) return x;
    return 1 << (31 - __builtin_clz(x));
}
int main(){
    long long n;
    cin>>n;
    cout<<NextPowerOfTwo(n)<<'\n'<<PrevPowerOfTwo;
    return 0;
}
```
:::
==Giải thích:== 
-Hàm NextPowerOfTwo(x): trả về lũy thừa của hai bé nhất không nhỏ hơn x.
-Hàm NextPowerOfTwo(x): trả về lũy thừa của hai lớn nhất không lớn hơn x.

---

**1.23.GrayCode(X) InverseGrayCode(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
int main(){
    
}
```
:::
-Hàm GrayCode(x): idk
-Hàm InverseGrayCode(x): idk

---

**1.24.ReverseBit(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ReverseBit(long long x){
    
}
```
:::
==Giải thích:== Đảo ngược số bằng bit.

---

**1.25.GenAllBinary(N) GenAllTernary(N) GenAllQuaternary(N) GenAllGrayCode(N)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
// wth ;-;
```
:::
::::
::::spoiler **2.Bitmask Bultin**
::::
::::spoiler **3.Modular Arithmetic**
[SPY_MOD](https://hackmd.io/@spyofgame/oai#II3---Modular-Arithmetic)
**3.1.ModFix(A, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModFix(long long a,long long p){
    return a%p;
}
int main(){
    long long x,y;
    cin>>x>>y
    cout<<ModFix(x, y);
    return 0;
}
```
:::

==Giải thích:==
-Hàm  :
**3.2.ModNeg(A, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModNeg(long long a,long long p){
    reuturn abs(a)%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModNeg(x,y);
    return 0;
}
```
:::
-Hàm  :
**3.3.ModInc(A, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModInc(long long a,long long p){
    return (a+1)%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModInc(x,y);
    return 0;
}
```
-Hàm:
:::
-Hàm:
**3.4.ModDec(A,P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModDec(long long a,long long p){
    return (a-1)%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModDec(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.5.ModInv(A, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModInv(long long a,long long p){
    return 1/a%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModInv(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.6.ModFib(N, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModFib(long long n,long long p){
    if(n==1||n==0) return n;
    return (ModFib(n-1)%p+ModFib(n-2)%p)%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModFib(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.7.ModLucas(N, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModLucas(long long n,long long p){
    if(n==1) return 1;
    if(n==0) return 2;
    return (ModLucas(n-1,p)%p+ModLucas(n-2,p)%p)%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModLucas(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.8.ModFac(N, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModFact(long long n,long long p){
    if(n==1) return 1;
    return (n%p*ModFact(n-1,p)%p)%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModFact(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.9.ModInvFact(N, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModInvFact(long long n,long long p){
    if(n==1) return 1;
    return ((1/n%p*1)/(ModFact(n-1,p)%p))%p;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<ModInvFact(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.10.ModAdd(A, B, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModAdd(long long a,long long b,long long p){
    return (a%p+b%p)%p;
}
int main(){
    long long x,y,p;
    cin>>x>>y>>p;
    cout<<ModAdd(x,y,p);
    return 0;
}
```
-Hàm  :
:::
**3.11.ModSub(A, B, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModSub(long long a,long long b,long long p){
    return (a%p-b%p)%p;
}
int main(){
    long long x,y,p;
    cin>>x>>y>>p;
    cout<<ModSub(x,y,p);
    return 0;
}
```
-Hàm  :
:::
**3.12.ModMul(A, B, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModMul(long long a,long long b,long long p){
    return (a%p*b%p)%p;
}
int main(){
    long long x,y,p;
    cin>>x>>y>>p;
    cout<<ModMul(x,y,p);
    return 0;
}
```
-Hàm  :
:::
**3.13.ModDiv(A, B, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModDiv(long long a,long long b,long long p){
    return (a%p*(1/b)%p)%p;
}
int main(){
    long long x,y,p;
    cin>>x>>y>>p;
    cout<<ModDiv(x,y,p);
    return 0;
}
```
-Hàm  :
:::
**3.14.ModPow(A, B, P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModPow(long long x,long long n,long long p){
    int res=1;
    for(int i=0;i<n;++i){
        res*=x%p;
    }
    return res%p;
}
int main(){
    long long x,y,p;
    cin>>x>>y>>p;
    cout<<ModPow(x,y,p);
    return 0;
}
```
-Hàm  :
:::
**3.15.DivFloor(X, Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long DivFloor(long long x,long long y){
    return x/y;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<Divfloor(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.16.DivCeil(X, Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long DivCeil(long long x,long long y){
    return (x+y-1)/y;
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<DivCeil(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.17.DivRound(X, Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long DivRound(long long x,long long y){
    return long long(long double(x)/y+0,5);
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<DivCeil(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.18.GCD(X, Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long GCD(long long x,long long y){
    if(!(y)) return x;
    return GCD(y,x%y);
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<GCD(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.19.LCM(X, Y)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long GCD(long long x,long long y){
    if(!(y)) return x;
    return GCD(y,x%y);
}
long long LCM(long long x,long long y){
    return x*y/GCD(x,y);
}
int main(){
    long long x,y;
    cin>>x>>y;
    cout<<LCM(x,y);
    return 0;
}
```
-Hàm  :
:::
**3.20.ExtGCD(X,Y)**
**3.21.ModAnk(N,K,P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModFact(long long n,long long p){
    if(n==1) return 1;
    return (n%p*ModFact(n-1,p)%p)%p;
}
long long ModAnk(long long n,long long k,long long p){
    return (ModFact(n,p)/ModFact(n-k,p))%p;
}
int main(){
    long long x,y,bruh;
    cin>>x>>y>>bruh;
    cout<<ModAnk(x,y,bruh);
    return 0;
}
```
-Hàm  :
:::
**3.22.ModEq(A,B,P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool ModEq(long long a,long long b,long long p){
    return (a%p==b%p);
}
int main(){
    long long x,y,p;
    cin>>x>>y>>p;
    cout<<(ModEq(x,y,p)?"YES":"NO");
    return 0;
}
```
-Hàm  :
:::
**3.23.ModPow2(A,B,P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModPow2(long long n,long long p){
    int res=1;
    for(int i=0;i<n;++i){
        res=(res*2)%p;
    }
    return res;
}
int main(){
    long long x,p;
    cin>>x>>p;
    cout<<ModPow2(x,p);
    return 0;
}
```
-Hàm  :
:::
**3.23.ModSquare(A,B,P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModSquare(long long n,long long p){
    int res=n%p;
    return (res*res)%p   ;
}
int main(){
    long long x,p;
    cin>>x>>p;
    cout<<ModSquare(x,p);
    return 0;
}
```
-Hàm  :
:::
**3.24.ModDiv2(A,B,P)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
long long ModDiv2(long long n,long long p){
    int res=n%p;
    return (res/2)%p   ;
}
int main(){
    long long x,p;
    cin>>x>>p;
    cout<<ModDiv2(x,p);
    return 0;
}
```
-Hàm  :
:::
::::
::::spoiler **4.Number Theory**
**3.25.IsSquare(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool IsCube(long long x){
    int i=0;
    for(;i*i<=x;++i){
        if(i*i==x) return true;
    }
    return false;
}
int main(){
    long long x;
    cin>>x;
    cout<<(IsSquare(x)?"YES":"NO");
    return 0;
}
```
-Hàm  :
:::
**3.26.IsCube(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool IsCube(long long x){
    int i=0;
    for(;i*i*i<=x;++i){
        if(i*i*i==x) return true;
    }
    return false;
}
int main(){
    long long x;
    cin>>x;
    cout<<(IsCube(x)?"YES":"NO");
    return 0;
}
```
-Hàm  :
:::
**3.27.IsKthRoot(X)**
**3.28.SqrtFloor(X)**
**3.29.SqrtCeil(X)**
**3.30.IsSqrtOf(X, N)**
**3.31.IsPrime(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
bool IsPrime(long long x){
    if(n<=1) return false;
    if(n==2||n==3) return true;
    if(n%2==0||n%3==0) return false;
    for(int i=5;i*i<=n;i+=6){
        if(n%i==0||n%(i+2)==0)return false;
    }
    return true;
}
int main(){
    long long x;
    cin>>x;
    cout<<(IsPrime(x)?"YES":"NO");
    return 0;
}
```
-Hàm  :
:::
**3.32.IsPrime(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
using namespace std;
const int maxn = 1000000 + 5;
bool is_prime[maxn];
void Sieve(int n){
    for (int i = 2; i <= n; i++)
        is_prime[i] = true;
    for (int i = 2; i * i <= n; i++) {
        if (is_prime[i]) {
            for (int j = i * i; j <= n; j += i)
                is_prime[j] = false;
        }
    }
}
int main(){
    long long n;
    cin>>n;
    Sieve(1000005);
    int cnt=0;
    for(int i=2;cnt<n;++i){
        if(is_prime[i]) {cout<<i<<" ";cnt++;}
    }
    return 0;
}
```
-Hàm  :
::: 
**3.33.DivisorsOf(X)**
:::spoiler **CODE và giải thích**
```cpp=
#include <iostream>
#include <vector>
using namespace std;
vector<int> DivisorsOf(long long x){
    int n=DivisorsOf.size()
}
int main(){
    long long x;
    cin>>x;
    cout<<(DivisorsOf(x)?"YES":"NO");
    return 0;
}
```
-Hàm  :
:::
::::