You are on page 1of 12

- Ma trận:

struct matrix
{
ll row, col;
ll a[101][101];
matrix (int row, int col) : row(row), col(col)
{
memset (a, 0, sizeof(a));
}
};

- Nhân ma trận:
matrix nhan (matrix A, matrix B)
{
matrix C(A.row, B.col);
for (int i = 0; i < A.row; i++)
{
for (int j = 0; j < B.col; j++)
{
for (int k = 0; k <= A.col; k++)
{
C.a[i][j] += A.a[i][k]*B.a[k][j];
C.a[i][j] %= mod;
}
}
}
return C;
}

- Mũ ma trận:
matrix power (matrix A,ll n)
{
matrix res(A.row, A.col);
for (int i = 0; i < A.row; i++)
res.a[i][i]=1;
while (n > 0)
{
if (n & 1)
res=nhan(res,A);
A = nhan(A,A);
n /= 2;
}
return res;
}

- Quy hoạch động cái túi:


+ Lấy số lượng vô hạn
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, m, w[1005], v[10005], dp[10005], kq = -1e18;
int main()
{
cin>>n>>m;
for (int i = 1; i <= n; i++)
cin>>v[i]>>w[i];
for (int i = 1; i <= n; i++)
for (int j = w[i]; j <= m; j++)
dp[j] = max(dp[j], dp[j-w[i]] + v[i]);
cout<<dp[m];
}
+ Lấy 1 lần:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, m, w[5005], v[5005], dp[5005], kq = -1e18;
int main()
{
cin>>n>>m;
for (int i = 1; i <= n; i++)
cin>>w[i]>>v[i];
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= w[i]; j--)
{
dp[j] = max(dp[j], dp[j-w[i]] + v[i]);
kq = max(dp[j], kq);
}
}
cout<<kq;
}

- Phân tích thừa số nguyên tố:


ll m, nt[1000005], dem[1000005];
void pttsnt (long long n)
{
memset (nt, 0, 1000005);
memset (dem, 0, 1000005);
m = 0;
for (long long i = 2; i <= sqrt(n); i++)
{
if (n % i == 0)
{
nt[++m] = i;
while (n % i == 0)
{
dem[m]++;
n = n / i;
}
}
}
if (n > 1)
nt[++m] = n, dem[m] = 1;
}

- Kiểm tra số nguyên tố:


+ Check nguyên tố: n > 10^6: chậm
bool snt (ll n)
{
for (int i = 2; i <= sqrt(n); i++)
if (n % i == 0)
return false;
return n > 1;
}
+
nguyên tố: n < 10^6: nhanh
const ll N = 1e6+5;
bool NT[N];
void sang ()
{
memset (NT, true, N);
NT[0] = NT[1] = false;
for(int i = 2; i <= sqrt(N); i++)
if(NT[i] == true)
for(int j = i * i; j <= N; j += i)
NT[j] = false;
}

- Kiểm tra số chính phương:


bool scp (ll n)
{
ll k = sqrt(n);
return k*k == n;
}

- Kiểm tra xâu đối xứng bằng Hash:


#include<bits/stdc++.h>
#define nmax 10000007
#define nmax2 1000006
#define nmax3 100005
#define mod 1000000000
#define fi first
#define se second
#define ma -1e18
#define mi 1e18
#define ll long long
using namespace std;
ll H[nmax2],hashh[nmax2];
ll m , t;
string s;
void f(){
H[0]=1;
for (int i =1;i<=s.size();i++)
{
H[i]=H[i-1]*31%m;
}
}
void hh()
{
hashh[0]=0;
for (int i = 1;i<=s.size();i++)
hashh[i]=(hashh[i-1]*31+(s[i-1]-'a'+1))%m;
}
ll tam(ll l , ll r)
{
ll ans=0;
ans=(hashh[r]-hashh[l-1]*H[r-l+1])%m;
if (ans<0) ans+=m;
return ans;
}
int main()
{ start();
cin >>m;
cin >>s;
f();
hh();
cin >>t;
while(t--){
ll l , r;
cin >>l >>r;
cout <<tam(l,r)<<"\n";
}
}

- Sàng -> Số:


ll tong (string n)
{
ll s = 0, i = 0, scs;
scs = n.size();
while (scs >= 1)
{
s = s*10 + n[i]-48;
i++;
scs--;
}
return s;
}

- Tìm kiếm nhị phân:


+ Tìm vị trí của x trong mảng:
ll a[100005];
ll tknp(ll dau, ll cuoi, ll x)
{
ll ans;
while (dau <= cuoi)
{
ll giua = (dau + cuoi)/2;
if (a[giua] <= x)
{
dau = giua+1;
ans = dau;
}
else
cuoi = giua - 1;
}
return ans;
}
+ Kiểm tra xem x có trong mảng:
ll a[100005];
ll tknp(ll dau, ll cuoi, ll x)
{
ll ans;
while (dau <= cuoi)
{
ll giua = (dau + cuoi)/2;
if (a[giua] <= x)
{
dau = giua+1;
return true;
}
else
cuoi = giua - 1;
}
return false;
}

ll n, a[100001], m, x;
ll chiadoan (ll k)
{
ll s = 0;
for (int i = 1; i <= n; i++)
if (a[i] > k)
s = s + a[i] - k;
return s;
}
ll tknp (ll h)
{
ll dau = 1, cuoi = 1e18, giua, ans = 0;
while (dau <= cuoi)
{
ll giua = (dau + cuoi)/2;
if (chiadoan(giua)>=h)
{
ans = giua;
dau = giua + 1;
}
else
cuoi = giua - 1;
}
return ans;
}

- Phép nhân số lớn:


#include <bits/stdc++.h>
using namespace std;
#define ll long long
string a, b;
ll c, s1, s2;
ll cal (string a, ll c)
{
ll sum = 0;
for (int i = 0; i < a.size(); i++)
sum = (sum * 10 + a[i] - '0') % c;
return sum;
}
int main()
{
cin>>a>>b>>c;
s1 = cal(a, c);
s2 = cal(b, c);
//cout<<s1<<" "<<s2<<"\n";
cout<<(s1 * s2) % c;
}
- Tìm hình vuông có dt lớn nhất trong bảng
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll m, n, a[1005][1005], dp[1005][1005], kq = -1e18;
int main()
{
cin>>n>>m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin>>a[i][j];
dp[0][0] = 0;
dp[1][0] = 0;
dp[0][1] = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (a[i][j] == a[i][j-1] && a[i][j] == a[i-1][j] && a[i][j] == a[i-1][j-1])
dp[i][j] = min(dp[i][j-1], min(dp[i-1][j], dp[i-1][j-1])) + 1;
else
dp[i][j] = 1;
kq = max(dp[i][j], kq);
}
}
cout<<kq;
}

- Tìm dãy con có tổng lớn nhất:


#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, a[1000005], s[1000005], ans = 0, nmin = 0;
int main()
{
cin>>n;
for (int i = 1; i <= n; i++)
cin>>a[i];
s[0] = 0;
for (int i = 1; i <= n; i++)
s[i] = s[i-1] + a[i];
for (int i = 1; i <= n; i++)
{
nmin = min(nmin, s[i]);
ans = max(ans, s[i] - nmin);
}
cout<<ans;
}
- Dãy con:
- Chia tăng --> tìm không tăng:
- Chia không tăng --> tìm tăng:
- Chia giảm --> tìm không giảm:
- Chia không giảm --> tìm giảm:

- tìm không tăng: b[mid] >= a[i]


- tìm tăng: b[mid] < a[i]
- tìm không giảm: b[mid] <= a[i]
- tìm giảm: b[mid] > a[i]

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N = 1e5 + 5;
ll a[N], b[N], x, n, d = 0;
int main()
{
cin>>n;
fill(b, b + n + 1, N);
for (int i = 0; i < n; ++i)
cin>>a[i];
for (int i = 0; i < n; ++i)
{
ll id = 0, L = 1, R = d;
while (L <= R)
{
ll mid = (L + R) / 2;
if (b[mid] < a[i])
{
id = mid;
L = mid + 1;
}
else
R = mid - 1;
}
if (id == d)
d++;
b[id+1] = a[i];
}
cout<<d<<"\n";
return 0;
}

- Sàng ước:
void sanguoc()
{
for (int i = 1; i <= 1000005; i++)
for (int j = i; j <= 1000005; j+=i)
f[j]++ ;
}
- Tổng trên ma trận:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll m, n, t, a[205][205], r1, r2, l1, l2, s[205][205];
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>m>>n;
cin>>t;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
cin>>a[i][j];
s[0][0] = 0;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j];
while (t--)
{
cin>>l1>>l2>>r1>>r2;
cout<<s[r1][r2] - s[r1][l2-1] - s[l1-1][r2] + s[l1-1][l2-1]<<"\n";
}
}

- Tìm tổng không liền kề lớn nhất:


#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n, a[100005], dp[100005], m = 0;
int main()
{
cin>>n;
for (int i = 1; i <= n; i++)
cin>>a[i];
dp[0] = 0;
dp[1] = max(m, a[1]);
for (int i = 1; i <= n; i++)
dp[i] = max(dp[i-2]+a[i], dp[i-1]);
cout<<dp[n];
}
- 1 xâu gồm chữ số và chữ cái thường, in ra số bé nhất từ các chữ cái giữ nguyên thứ tự:
#include <bits/stdc++.h>
#define ll long long
#define nmax 1000006
using namespace std;
ll k, dem=0, j;
string s, n;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//freopen("yoimiya.INP","r",stdin);
//freopen("yoimiya.OUT","w",stdout);
cin>>k>>s;
for(int i=0; i<s.size(); i++)
{
if (s[i]>='0'&&s[i]<='9')
{
dem++;
n=n+s[i];
}
}
while(j<dem-k)
for(int i=0; i<n.size(); i++)
{
if(n[i]-48<n[i-1]-48)
{
n.erase(i-1,1);
j++;
break;
}
if(i==n.size()-1)
{
j++;
n.erase(i,1);
}
}
cout<<n;
}

- Xóa k số sao cho còn lại lớn nhất:


#include <bits/stdc++.h>
#define ll long long
using namespace std;
string s,t;
ll k,dem=0;
stack<char> a;
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin>>s>>k;
for(int i=0; i<s.size(); i++)
{
while(a.empty() == false && s[i]>a.top() && dem<k)
{
a.pop();
dem++;
}
a.push(s[i]);
}
while(dem<k)
{
dem++;
a.pop();
}
while(!a.empty())
{
char m = a.top();
t = m + t;
a.pop();
}
cout<<t;
}

- SOLUONGDOANCONCOTONGBANG0:
#include<bits/stdc++.h>
#define nmax 10000007
#define nmax2 1000006
#define nmax3 100005
#define mod 1000000007
#define fi first
#define se second
#define ma -1e18
#define mi 1e18
#define ll long long
using namespace std;
ll a[nmax2],dp[nmax2+1];
map<ll,ll>d;
ll n,s=0;
int main(){
cin >>n;
for (int i =1;i<=n;i++)
cin >>a[i];
for (int i =1;i<=n;i++){
dp[i]=dp[i-1]+a[i];
d[dp[i]]++;
}
for (int i =1;i<=n;i++){
d[dp[i]]--;
if(dp[i]==0) s++;
s+=d[dp[i]];
}
cout <<s;
}

- Nhân chống tràn


(A*B)%MOD
yoimiya nhan(A,B,MOD)
{
A%=MOD; B%MOD:
yoimiya q=(long double)A*B%MOD;
return (A*B-q*MOD)%MOD;
}
MOD cho 1 số to (rất to)
yoimiya mod(string n)
{
yoimiya ans=0;
for (int i=0;i<n.size();i++)
ans=(ans*10+n[i]-'0')%c;
return ans;
}

- Đệ quy mũ:
ll mu (ll a, ll n)
{
ll res = 1;
if (n == 1)
return a%mod;
if (n & 1)
res = (res * a)%mod;
a = (a*a)%mod;
return (res*mu(a, n/2))%mod;
}

You might also like