0% found this document useful (0 votes)
13 views

tem5

Uploaded by

phamducluongwww
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views

tem5

Uploaded by

phamducluongwww
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 25

- ĐỆ QUY QUAY LUI

- SINH TỔ HỢP TẬP k CỦA S


{
int n, k;
vector <int> curSubset;

//Hàm đệ quy
void printSubset()
{
for (int i : curSubset) cout << i << " ";
cout << "\n";
}

void genSubset(int pos)


{
int lastNum = (curSubset.empty() ? 0 : curSubset.back()); //số cuối cùng được
chọn
for (int i = lastNum + 1; i <= n; i ++)
{
curSubset.push_back(i);
if (curSubset.size() == k) printSubset();
else genSubset(pos + 1);
curSubset.pop_back();
}
}

int main()
{
cin >> n >> k;
curSubset.clear();
genSubset(1);

return 0;
}

------
- SỐ HỌC
---------------------------------------------------------------------
* Tính tổ hợp Ckn tính trước
for (int i = 0; i <= n; i++){
C[i][0] = 1 % MOD;
for (int k = 1; k <= i; k++){
C[i][k] = (C[i - 1][k - 1] + C[i - 1][k]) % MOD;
}
}
-----------------------------------------------------------------------
* Sàng Eratosthenes
const int maxn = 1000000 + 5; //10^6 + 5
bool is_prime[maxn];
void Eratosthenes(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]) {
// j sẽ bắt đầu chạy từ i * i
for (int j = i * i; j <= n; j += i)
is_prime[j] = false;
}
}
}
----------
* Ptich số ngto
const int maxn = 1000000 + 5; //10^6 + 5
int min_prime[maxn];
void sieve(int n){
for (int i = 2; i * i <= n; ++i) {
if (min_prime[i] == 0) { //nếu i là số nguyên tố
for (int j = i * i; j <= n; j += i) {
if (min_prime[j] == 0) {
min_prime[j] = i;
}
}
}
}
for (int i = 2; i <= n; ++i) {
if (min_prime[i] == 0) {
min_prime[i] = i;
}
}
}
vector<int> factorize(int n) {
vector<int> res;
while (n != 1) {
res.push_back(minPrime[n]);
n /= minPrime[n];
}
return res;
}
------------------------------------------------------------------------

- CẤU TRÚC DỮ LIỆU


-------
* Segmentree
struct Segtree
{
int tree[4*N];
void Update(int id, int l, int r,int p, int val)
{
if(l==r){
tree[id] = val;return;
}
int mid = (l+r)/2;
if(mid >= p) Update(2*id,l,mid,p,val);
else Update(2*id+1,mid+1,r,p,val);
tree[id] = min(tree[2*id],tree[2*id+1]);
}
int get(int id, int l, int r, int u, int v)
{
if(l > v || r < u) return 1e18;
if(u <= l && r <= v) return tree[id];
int mid = (l+r)/2;
return min(get(2*id,l,mid,u,v),get(2*id+1,mid+1,r,u,v));
}
};
-----------------
* BIT2D

#include <bits/stdc++.h>
using namespace std;
int Bit[1003][1003],n,m,q,e,x,y,x1,x2,_ymot,y2,a[1004][1004];
void update(int x, int y, int val)
{
for(;x <= n; x += x&(-x))
for(int j = y ;j <= m; j += j&(-j))
Bit[x][j] += val;
}
int get(int x, int y)
{
int res = 0;
for(;x > 0; x -= x&(-x))
for(int j = y;j > 0; j -= j&(-j))
res += Bit[x][j];
return res;
}
int main()
{
cin >> n >> q;
m = n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
char o;
cin >> o;
if(o == '*') a[i][j] = 1;
update(i,j,a[i][j]);
}
}

while(q--)
{
cin >> e;
if(e == 1)
{
cin >> x >> y;
if(get(x,y) - get(x-1,y) - get(x,y-1)+get(x-1,y-1) == 1) update(x,y,-1);
else update(x,y,1);
}
else
{
cin >> x1 >> _ymot >> x2 >>y2;
cout << get(x2,y2) - get(x1-1,y2) - get(x2,_ymot-1) +get(x1-1,_ymot-1)
<<'\n';
}
}
}
----------------------------------------------------------------------
-BIT
struct Bittree{

int BIT[N];
void update(int id, int val)
{
for(; id <= n; id += id&(-id))
BIT[id] += val;
}
int getSum(int id)
{
int res = 0;
for(;id > 0; id -= id&(-id))
res+= BIT[id];
return res;
}
int get(int l, int r)
{
return (getSum(r) - getSum(l-1));
}
}
---------------------------------------------------------------------
* 1D sprase table
////QUERY SUM
// LG là số lớn nhất thoả 2^LG < N
// ví dụ: N = 10^5 thì LG = 16 vì 2^16 = 65536
int a[N], st[LG + 1][N];
void preprocess() {
for (int i = 1; i <= n; ++i) st[0][i] = a[i];
for (int j = 1; j <= LG; ++j)
for (int i = 1; i + (1 << j) - 1 <= n; ++i)
st[j][i] = st[j - 1][i] + st[j - 1][i + (1 << (j - 1))];
}
int querySum(int l, int r) {
int len = r - l + 1;
int sum = 0;
for (int j = 0; (1 << j) <= len; ++j)
if (len >> j & 1) {
sum = sum + st[j][l];
l = l + (1 << j);
}
return sum;
}
///// QEUERY _MIN
// LG là số lớn nhất thoả 2^LG < N
// ví dụ: N = 10^5 thì LG = 16 vì 2^16 = 65536
int a[N], st[LG + 1][N];
void preprocess() {
for (int i = 1; i <= n; ++i) st[0][i] = a[i];
for (int j = 1; j <= LG; ++j)
for (int i = 1; i + (1 << j) - 1 <= n; ++i)
st[j][i] = min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
}
int queryMin(int l, int r) {
int k = __lg(r - l + 1);
return min(st[k][l], st[k][r - (1 << k) + 1]);
}

------
2D Sprase_tablse
int a[M][N], st[LGM + 1][M][LGN + 1][N];
void preprocess() {
for (int k = 0; k <= LGM; ++k) {
for (int i = 1; i + (1 << k) - 1 <= m; ++i) {
for (int l = 0; l <= LGN; ++l) {
for (int j = 1; j + (1 << l) - 1 <= n; ++j) {
if (k == 0) {
if (l == 0) {
st[0][i][0][j] = a[i][j];
}
else {
st[0][i][l][j] = min(st[0][i][l - 1][j], st[0][i][l -
1][j + (1 << (l - 1))]);
}
}
else {
st[k][i][l][j] = min(st[k - 1][i][l][j], st[k - 1][i + (1
<< (k - 1))][l][j]);
}
}
}
}
}
}
int getMin(int x, int y, int a, int b) {
int k = __lg(a - x + 1);
int l = __lg(b - y + 1);
return min({ st[k][x][l][y],
st[k][x][l][b - (1 << l) + 1],
st[k][a - (1 << k) + 1][l][y],
st[k][a - (1 << k) + 1][l][b - (1 << l) + 1] });
___________________________________________________________________________________
_____
______HLD
#include<bits/stdc++.h>
using namespace std;
const int MaxN = 1e5 + 5;

int N, Q;
int Val[MaxN];
vector<int> AdjList[MaxN]; // input

int Par[MaxN]; // parent


int Depth[MaxN]; // do sau cua node
int Sz[MaxN]; // kich thuoc cua cay con cho cac node
int Pos[MaxN]; // vi tri trong mang cua node
int Arr[MaxN]; // gia tri cua cac phan tu trong mang
int ChainID[MaxN]; // ChainID[i]: Chain ma i nam trong
int ChainHead[MaxN]; // ChainHead[i]: Node dau tien trong chain i
int CurChain, CurPos;

void Dfs(int s, int p = -1) {


Sz[s] = 1;
for(int u: AdjList[s]) {
if(u == p) continue;
Par[u] = s;
Depth[u] = Depth[s] + 1;
Dfs(u, s);
Sz[s] += Sz[u];
}
}

void Hld(int s, int p = -1) {


if(!ChainHead[CurChain]) {
ChainHead[CurChain] = s;
}
ChainID[s] = CurChain;
Pos[s] = CurPos;
Arr[CurPos] = s;
CurPos++;
int nxt = 0;
for(int u: AdjList[s]) {
if(u != p) {
if(nxt == 0 || Sz[u] > Sz[nxt]) nxt = u;
}
}
if(nxt) Hld(nxt, s);
for(int u: AdjList[s]) {
if(u != p && u != nxt) {
CurChain++;
Hld(u, s);
}
}
}

// find LCA

int LCA(int u, int v) {


while(ChainID[u] != ChainID[v]) {
if(ChainID[u] > ChainID[v]) {
u = Par[ChainHead[ChainID[u]]];
}
else {
v = Par[ChainHead[ChainID[v]]];
}
}
if(Depth[u] < Depth[v]) return u;
return v;
}

// Segment Tree

int ST[MaxN * 4];


void Build(int id, int l, int r) {
if(l == r) {
ST[id] = Val[Arr[l]];
return;
}
int mid = (l + r) / 2;
Build(id * 2, l, mid);
Build(id * 2 + 1, mid + 1, r);
ST[id] = ST[id * 2] ^ ST[id * 2 + 1];
}

void Upd(int id, int l, int r, int pos, int val) {


if (l > pos || r < pos) return;
if (l == r && l == pos) {
ST[id] = val;
return;
}
int mid = (l + r) / 2;
Upd(id * 2, l, mid, pos, val);
Upd(id * 2 + 1, mid + 1, r, pos, val);
ST[id] = ST[id * 2] ^ ST[id * 2 + 1];
}

int Calc(int id, int tl, int tr, int l, int r) {


if (tl > r || tr < l) return 0;
if (l <= tl && tr <= r) return ST[id];
int mid = (tl + tr) / 2;
return Calc(id * 2, tl, mid, l, r) ^ Calc(id * 2 + 1, mid + 1, tr, l, r);
}

// Update and queries

void Update(int x, int val) {


Upd(1, 1, N, Pos[x], val);
}

int Query(int u, int v) {


int lca = LCA(u, v);
int ans = 0;
while(ChainID[u] != ChainID[lca]) {
ans ^= Calc(1, 1, N, Pos[ChainHead[ChainID[u]]], Pos[u]);
u = Par[ChainHead[ChainID[u]]];
}
while(ChainID[v] != ChainID[lca]) {
ans ^= Calc(1, 1, N, Pos[ChainHead[ChainID[v]]], Pos[v]);
v = Par[ChainHead[ChainID[v]]];
}
if(Depth[u] < Depth[v]) {
ans ^= Calc(1, 1, N, Pos[u], Pos[v]);
}
else {
ans ^= Calc(1, 1, N, Pos[v], Pos[u]);
}
return ans;
}

// main

signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
freopen("cowland.in", "r", stdin);
freopen("cowland.out", "w", stdout);
cin >> N >> Q;
for(int i = 1; i <= N; i++) {
cin >> Val[i];
}
for(int i = 1; i < N; i++) {
int u, v;
cin >> u >> v;
AdjList[u].push_back(v);
AdjList[v].push_back(u);
}
CurPos = CurChain = 1;
Dfs(1);
Hld(1);
Build(1, 1, N);
while(Q--) {
int type;
cin >> type;
if(type == 1) {
// Update
int x, val;
cin >> x >> val;
Update(x, val);
}
else {
int u, v;
cin >> u >> v;
cout << Query(u, v) << '\n';
}
}
}
_____________________________________________________________________
- ĐỒ THỊ
__________

CẦU_KHỚP_TPLTMANH
#include <bits/stdc++.h>

using namespace std;

const int maxN = 10010;

int n, m;
bool joint[maxN];
int timeDfs = 0, bridge = 0;
int low[maxN], num[maxN];
vector <int> g[maxN];

void dfs(int u, int pre) {


int child = 0; // Số lượng con trực tiếp của đỉnh u trong cây DFS
num[u] = low[u] = ++timeDfs;
for (int v : g[u]) {
if (v == pre) continue;
if (!num[v]) {
dfs(v, u);
low[u] = min(low[u], low[v]);
if (low[v] == num[v]) bridge++;
child++;
if (u == pre) { // Nếu u là đỉnh gốc của cây DFS
if (child > 1) joint[u] = true;
}
else if (low[v] >= num[u]) joint[u] = true;
}
else low[u] = min(low[u], num[v]);
}
}

int main() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
for (int i = 1; i <= n; i++)
if (!num[i]) dfs(i, i);
int cntJoint = 0;
for (int i = 1; i <= n; i++) cntJoint += joint[i];

cout << cntJoint << ' ' << bridge;


}
____________________________________________________________
NÉN TPLT MẠNH

/*
tag:
*/
#include <bits/stdc++.h>

#define int long long


#define fi first
#define si second
#define LL long long
#define For(i,a,b) for (int i = (a); i <= (b); ++i)
#define DFor(i,a) for (int i = (a); i >= 0 ; --i)
#define Vector vector <LL>
#define Pair pair <LL,LL>
#define Map map <LL,LL>
#define MemS(f,k) memset((f),(k),sizeof(f))
#define bit(i,n) ((n>>i) & 1)
#define Vii vector<pair<int,int>>
#define setpr(x) cout<<setprecision(x)<<fixed
#define endl '\n'
#define Prior priority_queue< pair<int,int> , Vii, greater<Pair> >
using namespace std;

using ULL = unsigned long long ;

const int MOD = 1E9 + 7;


const int SIZE_N = 2E6 + 1;
const int SIZE_C = 5E6+ 1;
const int N = 5e5 + 1;

int coin[N],n,m;
Vector g[N], adj[N];
int id[N],low[N],tplt[N],r[N],f[N],Time = 0;
stack<int> st;
bool vis[N];
int cc = 0;

void Tarjan(int u){


id[u] = low[u] = ++Time;
st.push(u);
for(auto v : g[u])
if(!vis[v])
{
if(id[v]) low[u] = min(low[u],id[v]);
else{
Tarjan(v);
low[u] = min(low[u],low[v]);
}
}
if(low[u] == id[u])
{ cc++;
int Node = 0, Sum = 0;
do{
Node = st.top();
st.pop();
Sum += coin[Node];
tplt[Node] = cc;
vis[Node] = true;
}
while(Node != u);
f[cc] = Sum;
}
}
int Result = 0;
void DFS(int u , int p)
{
vis[u] = true;
for(auto v : adj[u])
{
if(!vis[v]) {
DFS(v,u);
}
r[u] = max(r[u],r[v]);
}
r[u] += f[u];
Result = max(Result,r[u]);
}
signed main(){
cin >> n >> m;
For(i,1,n) cin >> coin[i];
For(i,1,m){
int x,y;
cin >> x >> y;
g[x].push_back(y);
}
For(i,1,n){
if(!id[i]) Tarjan(i);
}
For(i,1,n){
for(auto x : g[i])
{
if(tplt[x] != tplt[i]) adj[tplt[i]].push_back(tplt[x]);
}
}
fill(vis+1,vis+n+1,false);
For(i,1,n) if(!vis[i]) DFS(i,0);
cout << Result;
}
_______________________________
TOPO SORT
#include <bits/stdc++.h>
#define int long long
#define fi first
#define si second
#define For(i,a,b) for (int i = (a), _b =(b); i <= _b; ++i)
#define all(v) v.begin(), v.end()
#define Unique(v) v.erase(unique(all(v)), v.end())
#define MASK(i) (1LL << (i))
#define bit(i,n) (((n)>>(i)) & 1)
#define Vii vector<pair<int,int>>
#define setpr(x) cout<<setprecision(x)<<fixed
#define Prior priority_queue< pair<int,int> , Vii, greater<Pair> >
using namespace std;

const int Mod = 1E9 + 7;


const long long INF = 4E18;
const int N = 2e5 + 1;
vector<pair<int,int> > g[N];
bool vis[N];
stack<int> s;
int n,m,t,p,dist[N];
void Topo(int u){
vis[u] = true;
for(auto x : g[u])
{
if(!vis[x.fi]) Topo(x.fi);
}
s.push(u);
}
signed main(){
cin >> n >> m;
For(i,1,m)
{
int u,v,w;
cin >> u >> v >> w;
g[u].push_back({v,w});
}
cin >> t >> p;
Topo(t);
fill(dist + 1, dist + n + 1, -INF);
dist[t] = 0;
while(!s.empty())
{
int u = s.top(); s.pop();
//cout << u << endl;
for(auto v : g[u])
{
if(dist[v.fi] <= dist[u] + v.si)
{
dist[v.fi] = dist[u] + v.si;
}
}
}
if(dist[p] == -INF) cout << "NO PATH";
else
cout << dist[p];
}
__________________________________
FORD_BELLMAN
#include <bits/stdc++.h>
#define int long long
#define fi first
#define si second
#define LL long long
#define For(i, a, b) for (int i = (a); i <= (b); ++i)
#define DFor(i, a) for (int i = (a); i >= 0; --i)
#define Vector vector<LL>
#define Pair pair<LL, LL>
#define Map map<LL, LL>
#define MemS(f, k) memset((f), (k), sizeof(f))
#define bit(i, n) ((n >> i) & 1)
#define Vii vector<pair<int, int>>
#define setpr(x) cout << setprecision(x) << fixed
using namespace std;

using ULL = unsigned long long;

const int MOD = 1E18 + 7;


const int SIZE_N = 2E6 + 1;
const int SIZE_C = 5E6 + 1;
const int N = 2 * 1e5 + 1;
const int INF = 1e18;

int n, m;
struct adj
{
int v;
int u;
long long w;
};
int dist[N];
vector<adj> edges;
int trace[N];

void Ford_Bellman(int s)
{
fill(dist + 1, dist + n + 1, INF);
dist[s] = 0;
for (int i = 0; i < n; i++)
{
for (auto [u, v, W] : edges)
{
if (dist[v] > dist[u] + W)
{
dist[v] = dist[u] + W;
trace[v] = u;
if (i == n - 1)
{
cout << "YES" << endl;
vector<int> cycle;
int node = v;
// for (int j = 0; j < n; j++)
// {
// node = trace[node];
// }
int start = node;
while (true)
{
cycle.push_back(node);
node = trace[node];
if (node == start)
break;
} cycle.push_back(start);
reverse(cycle.begin(), cycle.end());

for (int c : cycle)


{
cout << c << " ";
}
exit(0);
}
}
}
}
}

signed main()
{
cin >> n >> m;

For(i, 1, m)
{
int x, y, w;
cin >> x >> y >> w;
edges.push_back({x, y, w});
//edges.push_back({y,x,w});
}
Ford_Bellman(1);

cout << "NO";


}
_________________________________________
KÓARAJU

/*
tag:
*/
#include <bits/stdc++.h>

#define int long long


#define fi first
#define si second
#define LL long long
#define For(i,a,b) for (int i = (a); i <= (b); ++i)
#define DFor(i,a) for (int i = (a); i >= 0 ; --i)
#define Vector vector <LL>
#define Pair pair <LL,LL>
#define Map map <LL,LL>
#define MemS(f,k) memset((f),(k),sizeof(f))
#define bit(i,n) ((n>>i) & 1)
#define Vii vector<pair<int,int>>
#define setpr(x) cout<<setprecision(x)<<fixed
#define endl '\n'
#define Prior priority_queue< pair<int,int> , Vii, greater<Pair> >
using namespace std;

using ULL = unsigned long long ;

const int MOD = 1E9 + 7;


const int SIZE_N = 2E6 + 1;
const int SIZE_C = 5E6+ 1;
const int N = 5e5 + 1;

int n,m;
Vector g[N],Tg[N];
stack<int> S;
bool vis[N];
int Count = 0;

void inp()
{
cin >> n >> m;
For(i,1,m) {
int x,y;
cin >> x >> y;
g[x].push_back(y);
Tg[y].push_back(x);
}
}
void Topo(int s)
{
vis[s] = true;
for(auto x : g[s])
if(!vis[x])
Topo(x);
S.push(s);
}
void DFS(int s)
{
vis[s] = true;
for(auto x : Tg[s])
{ if(!vis[x])
DFS(x);
}
}
void Kosaraju()
{
For(i,1,n)
{
if(!vis[i]) Topo(i);
}
fill(vis+1, vis+n+1, false);
Vector trace;
while(!S.empty()){
int node = S.top();
S.pop();
if(!vis[node]) DFS(node),Count++,trace.push_back(node);
}
if(Count == 1) cout << "YES";
else {
cout << "NO\n";
cout << trace[1] <<' ' << trace[0];
}
}
signed main(){
inp();
Kosaraju();
}

___________________
SMALL_TO_LARGE

/* author: Nohart K104 LHP */


/*
tag https://cses.fi/problemset/task/2101/
*/
#include <bits/stdc++.h>

#define int long long


#define fi first
#define si second
#define LL long long
#define For(i,a,b) for (int i = (a); i <= (b); ++i)
#define DFor(i,a) for (int i = (a); i >= 0 ; --i)
#define Vector vector <LL>
#define Pair pair <LL,LL>
#define Map map <LL,LL>
#define MemS(f,k) memset((f),(k),sizeof(f))
#define bit(i,n) ((n>>i) & 1)
#define Vii vector<pair<int,int>>
#define setpr(x) cout<<setprecision(x)<<fixed
#define endl '\n'
#define sz(x) (int)(x.size())
using namespace std;

using ULL = unsigned long long ;

const int MOD = 1E9 + 7;


const int SIZE_N = 2E6 + 1;
const int SIZE_C = 5E6+ 1;
const int N = 6*1e5 + 1;

int n,m,k;
Vii g[N],a[N];
int par[N], siz[N], Result[N];
void Make_set() {
For(i, 1, n) {siz[i] = 1; par[i] = i;}
}
int Find(int u) {
return (u == par[u]) ? u : par[u] = Find(par[u]);
}
void Union (int u, int v, int idx)
{
u = Find(u);
v = Find(v);
if(u == v) return ;
if(siz[u] < siz[v]) swap(u,v);
par[v] = u;
siz[u] += siz[v];

for(auto [x,y] : g[v])


{
if(Result[y] != -1) continue;
if(Find(x) == u)
{
Result[y] = idx; continue;
}
g[u].push_back({x,y});
}
}
signed main(){
cin >> n >> m >> k;
fill(Result + 1,Result + k + 1, - 1);
Make_set();
for(int i = 1; i <= m; i++)
{ int x,y;
cin >> x >> y;
a[i].push_back({x,y});
}
for(int i = 1; i <= k; i++)
{
int u,v;
cin >> u >> v;
if(u == v)
{
Result[i] = 0; continue;
}
g[u].push_back({v,i});
g[v].push_back({u,i});
}
for(int T = 1; T <= m; T++)
{
for(auto q : a[T])
{
int x = q.fi;
int y = q.si;
Union(x,y,T);
}
}
for(int i = 1; i <= k; i++) cout << Result[i] << endl;
}

/* author: Nohart K104 LHP_ Kintran */


/*
tag:
*/
#include <bits/stdc++.h>

#define int long long


#define fi first
#define si second
#define LL long long
#define For(i, a, b) for (int i = (a); i <= (b); ++i)
#define DFor(i, a) for (int i = (a); i >= 0; --i)
#define Vector vector<LL>
#define Pair pair<LL, LL>
#define Map map<LL, LL>
#define MemS(f, k) memset((f), (k), sizeof(f))
#define bit(i, n) ((n >> i) & 1)
#define Vii vector<pair<int, int>>
#define setpr(x) cout << setprecision(x) << fixed
#define endl '\n'
#define Prior priority_queue<pair<int, int>, Vii, greater<Pair>>
using namespace std;

using ULL = unsigned long long;

const int MOD = 1E9 + 7;


const int SIZE_N = 2E6 + 1;
const int SIZE_C = 5E6 + 1;
const int N = 5e5 + 1;
const int N2 = 600;
int par[N], siz[N], Result[N];
int a[N2][N2];
int n, m, k;
Vii queries[N];
bool use[N];
Vii adj[N],g[N];

const int di[4] = {-1, 0, 1, 0};


const int dj[4] = {0, 1, 0, -1};
void init (){
freopen("SHUTDOWN.inp","r",stdin);
freopen("SHUTDOWN.out","w",stdout);

ios_base :: sync_with_stdio(0);
cin.tie(0);
cout.tie(0);

}
bool ok(int i,int j){
return i >= 1 && i <= n && j >= 1 && j <= m;
}
void Make_set() {
For(i, 1, m * n) {siz[i] = 1; par[i] = i;}
}
int Find(int u) {
return (u == par[u]) ? u : par[u] = Find(par[u]);
}
void Union(int u, int v,int idx) {
u = Find(u);
v = Find(v);
if (u == v) return;
if (siz[u] < siz[v]) swap(u, v);
siz[u] += siz[v];
par[v] = u;

for(auto o : g[v])
{ int x = o.fi;
int y = o.si;
if(Result[y] != -1) continue;
if(Find(x) == u)
{
Result[y] = idx ; continue;
}
g[u].push_back({x,y});
}
}

signed main() {
init();
cin >> n >> m >> k;
Make_set();
fill( Result + 1, Result + k + 1, -1);
For(i,1,n)
For(j,1,m)
{
cin >> a[i][j];
adj[a[i][j]].push_back({i,j});
}
For(i,1,k){
int a,b;
cin >> a >> b;
if(a == b) {
Result[i] = a ; continue;
}
g[a].push_back({b,i});
g[b].push_back({a,i});
}

for(int l = m*n ; l > 0; l--)


{
use[l] = true;
for(auto x : adj[l])
{
int tmp1 = x.fi;
int tmp2 = x.si;
for(int q = 0; q < 4; q ++)
{
int i = tmp1 + di[q];
int j = tmp2 + dj[q];
if(ok(i,j) && use[a[i][j]]) {Union(a[i][j],l,l);}
}
}
}

for(int i = 1; i <= k ; i++) cout << Result[i] << endl;

}
_______________________________________________________________________

- XÂU
*tìm xâu xoay có thứ tự từ điển nhỏ nhất
#include <bits/stdc++.h>
using namespace std;

string booth(const string& s) {


string s2 = s + s;
int n = s.size();
vector<int> f(2 * n, -1);
int k = 0;

for (int j = 1; j < 2 * n; ++j) {


char sj = s2[j];
int i = f[j - k - 1];
while (i != -1 && sj != s2[k + i + 1]) {
if (sj < s2[k + i + 1]) {
k = j - i - 1;
}
i = f[i];
}
if (sj != s2[k + i + 1]) {
if (sj < s2[k]) {
k = j;
}
f[j - k] = -1;
} else {
f[j - k] = i + 1;
}
}

return s2.substr(k, n);


}
string s;
int main() {

cin >> s;

string result = booth(s);


cout << result << endl;

return 0;
}
-=----------------------------------------------------------

*HASH
9325366013
9507142283
9333449891
101
199
------------------------------------------------------------
*KMP

cin >> s >> t;


m = s.size(); s = '$' + s;
n = t.size(); t = '#' + t;

// tính mảng KMP


int kmp[MAX];
int k = kmp[1] = 0;
for (i : 2 -> m) {
while (k > 0 && s[i] != s[k + 1]) k = kmp[k];
kmp[i] = s[i] == s[k + 1] ? ++k : 0;
}
// độ phức tạp tính toán: O(m)
// chú ý: do kmp[i] < i với mọi i nên lệnh gán k = kmp[k] chắc chắn làm giảm giá
trị của biến k
// ta for i từ 2 đến m, mỗi lần for chỉ có 1 lần ++k (làm tăng giá trị biến k)
// -> biến k chỉ được tăng tối đa m lần -> cũng chỉ giảm tối đa m lần -> vòng while
với lệnh kmp[k] thực hiện không quá m lần -> ĐPT là O(m)

Sau khi tính mảng KMP, mảng match tính hoàn toàn tương tự (thay S bằng T). Chú ý,
mảng match tính từ 1 (chứ ko for từ 2 như mảng KMP)
int match[MAX];
int k = 0;
for (i : 1 -> n) {
while (k > 0 && t[i] != s[k + 1]) k = kmp[k];
match[i] = t[i] == s[k + 1] ? ++k : 0;
if (match[i] == m) { xâu S xuất hiện tại trong T tại vị trí i - m + 1 }
}

// độ phức tạp: O(n). Tương tự như trên, vòng while luôn làm giảm biến k nên chỉ
thực hiện được không quá n lần (do có tối đa n lần tăng biến k)

------------------------------------------
*MANACHER
#include<bits/stdc++.h>
using namespace std;
const int N = 6e6 + 8;
string tmp;
int ans = 0,vtri;
vector<int> p;
vector<char> s,t;
int len ,K;
void solvesub3()
{ int l = 0, r = -1,num = 0;
for(int i = 1; i <= K; i++)
{
for(int j = 0; j < tmp.size(); j++)
{
t[num] = tmp[j];
num++;
}
}
int n = 2*num,cnt = -1,k;
s.resize(n+10);
p.resize(n+10);
for(int i = 0; i < num; i++)
{
s[++cnt] = '#';
s[++cnt] = t[i];
}
s[++cnt] = '#';
for(int i = 0; i <= n; i++)
{ int j = r - i + l;
if(i > r) k = 1;
else k = min(p[j],r-i);
while(i-k > 0 && i + k < n && s[i-k] == s[i+k]) k++;
if(s[i-k] != s[i + k]) k--;
p[i] = k;
if(ans < p[i])
{
ans = k;
vtri = i;
}
if(i + k >= r)
{
l = i - k;
r = i + k;
}
}
for(int i = vtri - ans; i <= vtri + ans; i ++)
{
if(s[i] == '#') continue;
cout << s[i];
}

int main()
{ ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);

K = 1;
cin >> tmp;
len = tmp.size();
t.resize(len*K+10);
return solvesub3(),0;
}
#include<bits/stdc++.h>
using namespace std;
const int MaxN = 255;
int Cnt[MaxN][26];
int Cnt_Odd[MaxN];
int D_odd[MaxN];
int D_even[MaxN];
char c[MaxN][MaxN];
bool Ok[MaxN];
int N,M;
int Ans = 0;
bool Equal(int Row1, int Row2) {
if(!Ok[Row1]) return false;
if(!Ok[Row2]) return false;
for(int j = 0 ; j < 26 ; j++) {
if(Cnt[Row1][j] != Cnt[Row2][j]) return false;
}
return true;
}
void Calc_D_odd() {
int L = 1;
int R = 0;
for(int i = 1 ; i <= N ; i++) {
if(i > R) D_odd[i] = 0;
else D_odd[i] = min(R - i, D_odd[L + (R - i)]);
if (Ok[i]) while(i - D_odd[i] - 1 > 0 && i + D_odd[i] + 1 <= N && Equal(i -
D_odd[i] - 1, i + D_odd[i] + 1)) {
D_odd[i]++;
}
Ans += (D_odd[i] + Ok[i]);
if(i + D_odd[i] > R) {
R = i + D_odd[i];
L = i - D_odd[i];
}
}
}

void Calc_D_even() {
// D_even[i] is the value for the space between i and i + 1
int L = 1;
int R = 0;
for(int i = 1 ; i < N ; i++) {
int j = i + 1;
if(j > R) D_even[i] = 0;
else D_even[i] = min(R - j + 1, D_even[L + (R - j)]);
while(i - D_even[i] > 0 && j + D_even[i] <= N && Equal(i - D_even[i], j +
D_even[i])) {
D_even[i]++;
}
Ans += D_even[i];
if(i + D_even[i] > R) {
R = i + D_even[i];
L = j - D_even[i];
}
}
}
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> N >> M;
for(int i = 1 ; i <= N ; i++) {
cin >> c[i] + 1;
}
for(int c1 = 1 ; c1 <= M ; c1++) {
for(int c2 = c1 ; c2 <= M ; c2++) {
bool ok = true;
for(int i = 1 ; i <= N ; i++) {
int t = c[i][c2] - 'a';
Cnt[i][t]++;

if(Cnt[i][t] & 1) Cnt_Odd[i]++;


else Cnt_Odd[i]--;

if(Cnt_Odd[i] > ((c2 - c1 + 1) & 1)) Ok[i] = false;


else Ok[i] = true;
}
Calc_D_odd();
Calc_D_even();
}
for(int i = 1 ; i <= N ; i++) {
for(int j = 0 ; j < 26 ; j++) {
Cnt[i][j] = 0;
}
Cnt_Odd[i] = 0;
}
}
cout << Ans;
}
------------------------------------------
*TRIE
struct Trie{
struct Node{
Node* child[26];
int exist, cnt;

Node() {
for (int i = 0; i < 26; i++) child[i] = NULL;
exist = cnt = 0;
}
};

int cur;
Node* root;
Trie() : cur(0) {
root = new Node();
};

void add_string(string s) {
Node* p = root;
for (auto f : s) {
int c = f - 'a';
if (p->child[c] == NULL) p->child[c] = new Node();

p = p->child[c];
p->cnt++;
}
p->exist++;
}

bool delete_string_recursive(Node* p, string& s, int i) {


if (i != (int)s.size()) {
int c = s[i] - 'a';
bool isChildDeleted = delete_string_recursive(p->child[c], s, i + 1);
if (isChildDeleted) p->child[c] = NULL;
}
else p->exist--;

if (p != root) {
p->cnt--;
if (p->cnt == 0) {
delete(p); // Khác với cài đặt bằng mảng,
// ta có thể thực sự xóa đỉnh này đi
return true;
}
}
return false;
}

void delete_string(string s) {
if (find_string(s) == false) return;

delete_string_recursive(root, s, 0);
}

bool find_string(string s) {
Node* p = root;
for (auto f : s) {
int c = f - 'a';
if (p->child[c] == NULL) return false;
p = p->child[c];
}
return (p->exist != 0);
}
};

#include <bits/stdc++.h>
using namespace std;
// Tên chương trình
const string NAME = "code";
// Số test kiểm tra
const int NTEST = 100;

mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count());
#define rand rd

// Viết lại hàm random để sử dụng cho thuận tiện.


// Hàm random này sinh ngẫu nhiên số trong phạm vi long long
// Số sinh ra nằm trong [L;R].
long long Rand(long long L, long long R) {
assert(L <= R);
return L + rd() % (R - L + 1);
}

int main()
{
srand(time(NULL));
for (int iTest = 1; iTest <= NTEST; iTest++)
{
ofstream inp((NAME + ".inp").c_str());
// Code phần sinh test ở đây
inp.close();
// Nếu dùng Linux thì "./" + Tên chương trình
system((NAME + ".exe").c_str());
system((NAME + "_trau.exe").c_str());
// Nếu dùng linux thì thay fc bằng diff
if (system(("fc " + NAME + ".out " + NAME + ".ans").c_str()) != 0)
{
cout << "Test " << iTest << ": WRONG!\n";
return 0;
}
cout << "Test " << iTest << ": CORRECT!\n";
}
return 0;
}
bao loi
#include <bits/stdc++.h>
using namespace std;

// Kiểu điểm
struct Point {
int x, y;
};

// Tích có hướng của AB và AC


long long cross(const Point &A, const Point &B, const Point &C) {
return 1LL * (B.x - A.x) * (C.y - A.y) - 1LL * (C.x - A.x) * (B.y - A.y);
}

// A -> B -> C đi theo thứ tự theo chiều kim đồng hồ (-1), thẳng hàng (0), ngược
chiều kim đồng hồ (1)
int ccw(const Point &A, const Point &B, const Point &C) {
long long S = cross(A, B, C);
if (S < 0) return -1;
if (S == 0) return 0;
return 1;
}

// Trả về bao lồi với thứ tự các điểm được liệt kê ngược chiều kim đồng hồ
vector<Point> convexHull(vector<Point> p, int n) {
// Đưa điểm có tung độ nhỏ nhất (và trái nhất) lên đầu tập
for (int i = 1; i < n; ++i) {
if (p[0].y > p[i].y || (p[0].y == p[i].y && p[0].x > p[i].x)) {
swap(p[0], p[i]);
}
}

// Sắp xếp các điểm I theo góc tạo bởi trục hoành theo chiều dương và OI
sort(p.begin() + 1, p.end(), [&p](const Point &A, const Point &B) {
int c = ccw(p[0], A, B);
if (c > 0) return true;
if (c < 0) return false;
return A.x < B.x || (A.x == B.x && A.y < B.y);
});
// Tập bao lồi
vector<Point> hull;
hull.push_back(p[0]);

// Dựng bao lồi


for (int i = 1; i < n; ++i) {
while (hull.size() >= 2 && ccw(hull[hull.size() - 2], hull.back(), p[i]) <
0) {
hull.pop_back();
}
hull.push_back(p[i]);
}
return hull;
}
dien tich da giac
#include <bits/stdc++.h>
#define db long double
using namespace std;
pair<double,double> v[10000];
int main()
{ double x,y;
int n;
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> x >> y;
v[i] = {x,y};
}
long double area = 0;
for(int i = 1; i <= n; i++)
{
int j = i%n + 1;
area += (v[i].first - v[j].first)*(v[i].second+v[j].second);
}
area = abs(area)/2.0;
cout << fixed << setprecision(1);
cout << area;
return 0;
}

You might also like