Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
INDEX
NUMBER THEORY
SEGMENT TREE
//Build the segment tree //Range Query
void buildtree(int node, int start, int end) int query(int node, int start, int end, int qstart, int qend)
{ {
if(start>end) if(lazy[node]!=0)
return; marklazy(node,start,end);
if(start==end) if(qstart>end || qend<start || start>end )
{ return 1;
//leaf node logic if(start>=qstart && end<=qend)
return; return tree[node].mx;
} int mid = (start+end)/2;
int mid = (start+end)/2; int p = query(2*node,start,mid,qstart,qend);
buildtree(node*2, start, mid); int q = query(2*node+1,mid+1,end,qstart,qend);
buildtree(node*2+1, mid+1, end); //query logic
//merging logic return max(p,q);
merge(tree[node*2],tree[node*2+1],tree[node]); }
void update(int node, int start, int end, int qstart, int qend)
{
if(lazy[node]!=0) int mid = (start+end)/2;
marklazy(node,start,end); update(2*node,start,mid,qstart,qend);
if(qstart>end || qend<start || start>end ) update(2*node+1,mid+1,end,qstart,qend);
return; merge(tree[node*2],tree[node*2+1],tree[node]);
if(start>=qstart && end<=qend) }
{
tree[node].point += 1;
if(tree[node].point<tree[node].sz)
{
tree[node].mx = tree[node].facts[tree[node].point];
}
else
tree[node].mx = 1;
if(start!=end)
{
lazy[2*node] += 1;
lazy[2*node+1] += 1;
}
return;
}
DISTINCT SUBSTRING WITH SUFFIX ARRAY
int l=s.length();
int i,j;
suffix_array(s);
cum[0]=l-arr[0];
lcpar[0]=0;
for(i=1;i<l;i++)
lcpar[i]=lcp(arr[i],arr[i-1],l);
for(i=1;i<l;i++)
cum[i] = cum[i-1]+ (l-arr[i]-lcpar[i]);
while(q--)
{
int k;
cin>>k;
cout<<endl;
}
return 0;
}
O( (N+M) * sqrt N )
Input Output
5 3
11213 2
3 3
15
24
35
#include <cstdio> int main() {
#include <algorithm> int n;
using namespace std; scanf("%d", &n);
for(int i=0; i<n; i++)
#define N 311111 scanf("%d", &a[i]);
#define A 1111111
#define BLOCK 555 // ~sqrt(N) int m;
scanf("%d", &m);
int cnt[A], a[N], ans[N], answer = 0; for(int i=0; i<m; i++) {
scanf("%d%d", &q[i].L, &q[i].R);
struct node { q[i].L--; q[i].R--;
int L, R, i; q[i].i = i;
}q[N]; }
/* C implementation of search and insert operations // Returns new trie node (initialized to NULLs)
on Trie struct TrieNode *getNode(void)
Output : {
struct TrieNode *pNode = NULL;
the --- Present in trie
these --- Not present in trie pNode = (struct TrieNode *)malloc(sizeof(struct
their --- Present in trie TrieNode));
thaw --- Not present in trie
*/ if (pNode)
#include <stdio.h> {
#include <stdlib.h> int i;
#include <string.h>
#include <stdbool.h> pNode->isLeaf = false;
pNode->isLeaf = false;
return pNode;
}
// Returns true if key presents in trie, else false // Driver
bool search(struct TrieNode *root, const char *key) int main()
{ {
int level; // Input keys (use only 'a' through 'z' and lower case)
int length = strlen(key); char keys[][8] = {"the", "a", "there", "answer", "any",
int index; "by", "bye", "their"};
struct TrieNode *pCrawl = root;
char output[][32] = {"Not present in trie", "Present in trie"};
for (level = 0; level < length; level++)
{
index = CHAR_TO_INDEX(key[level]); struct TrieNode *root = getNode();
return 0;
}
ll segsieve(ll m,ll n)
{
ll b[n-m+10],q,x,i,j;
for(i=0;i<=n-m;i++)
b[i]=1;
if(m==1)
b[0]=0;
q=sqrt(n);
for(i=2;i<=q;i++)
{
x=(m/i);
x*=i;
if(i>=x)
x=i*2;
for(j=x;j<=n;j+=i)
{
if(j>=m)
b[j-m]=0;
}
}
for(i=m;i<=n;i++)
if(b[i-m])
printf("%lld\n",i);
printf("\n");
// In a weighted graph, we need to store vertex // Insert source itself in priority queue and initialize
// and weight pair for every edge // its distance as 0.
list< pair<int, int> > *adj; pq.push(make_pair(0, src));
dist[src] = 0;
public:
Graph(int V); // Constructor /* Looping till priority queue becomes empty (or all
distances are not finalized) */
// function to add an edge to graph while (!pq.empty())
void addEdge(int u, int v, int w); {
// The first vertex in pair is the minimum distance
// prints shortest path from s // vertex, extract it from priority queue.
void shortestPath(int s); // vertex label is stored in second of pair (it
}; // has to be done this way to keep the vertices
// sorted distance (distance must be first item
// Allocates memory for adjacency list // in pair)
Graph::Graph(int V) int u = pq.top().second;
{ pq.pop();
this->V = V;
adj = new list<iPair> [V]; // 'i' is used to get all adjacent vertices of a vertex
} list< pair<int, int> >::iterator i;
for (i = adj[u].begin(); i != adj[u].end(); ++i)
void Graph::addEdge(int u, int v, int w) {
{ // Get vertex label and weight of current adjacent
adj[u].push_back(make_pair(v, w)); // of u.
adj[v].push_back(make_pair(u, w)); int v = (*i).first;
} int weight = (*i).second;
int find ( struct subset subsets [ ] , int i ) -> if x & ( x 1 ) = 0 then number is power of 2
{ -> ( x | 1 << n ) returns the number x with nth bit set
if ( subsets [ i ].parent != i ) -> x ^ ( 1 << n ) toggles the state of the nth bit in the
subsets [ i ].parent = find ( subsets , subsets[i].parent ) ; number x
return subsets[i].parent ;
}
void Union ( struct subset subsets [ ] , int x , int y ) Euler tour:
{ -> for undirected graph:
int xroot = find ( subsets , x ) ; all vertices having non-zero degree must be
int yroot = find ( subsets , y ) ; connected.
if ( subsets [ xroot ].rank < subsets [ yroot ].rank) Eulerian path- 0 or 2 vertices can have odd degree.
subsets [ xroot ].parent = yroot ; Eulerian cycle- all vertices must have even degree.
else if ( subsets [ xroot ].rank > subsets [ yroot ].rank ) -> for directed graph
subsets [ yroot ].parent = xroot ; //these conditions are only for finding existence of
else Eulerian cycle
{ *all vertices having non-zero degree belong to a
subsets [ yroot ].parent = xroot ; single strongly connected components.
subsets [ xroot ].rank++ ; *indegree and outdegree for every vertex must be
} same.
}
15/47. Subsets of a subset generation: KMP Implementation
x=n ; //n is representing the subset void KMPSearch(char *pat, char *txt)
while ( 1 ) {
{ int M = strlen(pat);
int N = strlen(txt);
cout << x ;
int *lps = (int *)malloc(sizeof(int)*M);
if ( x == 0 ) int j = 0; // index for pat[]
break ; int i = 0; // index for txt[]
x = ( x -1 ) & n ; while (i < N)
} {
16/47. Biconnected graph: if (pat[j] == txt[i])
{
graph is biconnected if: j++;
->graph is connected. i++;
->there is no articulation point in the graph. }
if (j == M)
Matrix chain multiplication: {
printf("Found pattern at index %d \n", i-j);
j = lps[j-1];
// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n }
int MatrixChainOrder(int p[], int n) else if (i < N && pat[j] != txt[i])
{ {
int i, j, k, L, q; if (j != 0)
/* m[i,j] = Minimum no. of scalar multiplications j = lps[j-1];
needed to compute the matrix A[i]A[i+1]...A[j] = else
i = i+1;
A[i..j] */ }
for (i = 1; i < n; i++) }
m[i][i] = 0; }
// L is chain length. void computeLPSArray(char *pat, int M, int *lps)
for (L=2; L<n; L++) {
{ int len = 0; // lenght of the previous longest prefix
suffix
for (i=1; i<=n-L; i++) int i=1;
{ lps[0] = 0;
j = i+L-1; while (i < M)
m[i][j] = INT_MAX; {
for (k=i; k<=j-1; k++) if (pat[len] == pat[i])
{ {
len++;
// q = cost/scalar multiplications lps[i] = len;
q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]; i++;
if (q < m[i][j]) }
m[i][j] = q; else if(len != 0)
} {
len=lps[len-1];
}
}
} else
return m[1][n-1]; {
} lps[i] = 0;
i++;
}
}
}
Kruskal
bool isCyclicUtil {
(int v, bool visited[], bool *rs);
subsets[v].parent = v;
void TopologicalSortUtil
(int v, bool visited[], stack<int> &Stack); subsets[v].rank = 0;
public:
}
Graph(int V);
void addEdge(int v, int w); while (e < V - 1)
void BFS(int s);
{
void DFS();
bool isCyclic(); struct Edge next_edge = graph->edge[i++];
void TopologicalSort(); int x = find(subsets, next_edge.src);
};
Graph::Graph(int V) int y = find(subsets, next_edge.dest);
{ if (x != y)
this->V = V;
{
adj = new list<int>[V];
} result[e++] = next_edge;
void Graph::addEdge(int v, int w)
Union(subsets, x, y);
{
adj[v].push_back(w); }
}
}
void Graph::BFS(int s)
{ printf("edges in MST\n");
bool *visited = new bool[V]; for (i = 0; i < e; ++i)
for(int i=0;i<V;i++)
visited[i]=false; printf("%d -- %d == %d\n",
{ = graph->array[u].head;
visited[v] = true;
while (pCrawl != NULL)
recStack[v] = true;
list<int>::iterator i; {
for(i = adj[v].begin(); i != adj[v].end(); ++i)
int v = pCrawl->dest;
{
if (visited[*i]==false if (isInMinHeap(minHeap, v)
&& isCyclicUtil(*i, visited, recStack) )
&& pCrawl->weight < key[v])
return true;
else if (recStack[*i]) {
return true; key[v] = pCrawl->weight;
}
parent[v] = u;
} decreaseKey(minHeap, v, key[v]);
recStack[v] = false;
}
return false;
} pCrawl = pCrawl->next;
bool Graph::isCyclic()
}
{
bool *visited = new bool[V]; }
bool *recStack = new bool[V]; printArr(parent, V);
for(int i = 0; i < V; i++)
{ }
visited[i] = false; Bellman Ford
recStack[i] = false; for ( i = 1 ; i < V ; i++ )
} {
for(int i = 0; i < V; i++) for ( j = 0 ; j < E ; j++ )
if (isCyclicUtil(i, visited, recStack)) {
return true; int u = edge[j].src ;
return false; int v = edge[j].dest ;
} int weight = edge[j].weight ;
void Graph::TopologicalSortUtil if ( dist[u] != INT_MAX
(int v, bool visited[], stack<int> &Stack) && dist[u] + weight < dist[v] )
{ dist[v] = dist[u] + weight ;
visited[v]=true; }
list<int>::iterator i; }
for(i=adj[v].begin();i!=adj[v].end();i++)
if(visited[*i]==false)
TopologicalSortUtil(*i, visited, Stack);
Stack.push(v);
}
Floyd Warshall
void Graph::TopologicalSort()
void floydWarshell (int graph[][V])
{
{
stack<int> Stack;
int dist[V][V], i, j, k;
bool *visited = new bool[V];
for (i = 0; i < V; i++)
int i;
for (j = 0; j < V; j++)
for(i=0;i<V;i++)
dist[i][j] = graph[i][j];
visited[i]=false;
for (k = 0; k < V; k++)
for(i=0;i<V;i++)
{
if(visited[i]==false)
for (i = 0; i < V; i++)
TopologicalSortUtil(i, visited, Stack);
{
while(!Stack.empty())
for (j = 0; j < V; j++)
{
{
cout << Stack.top() << " ";
if (dist[i][k] + dist[k][j] < dist[i][j])
Stack.pop();
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
Union Find
}
class UF
printSolution(dist);
{
}
private:
Connected Components
int *id;
class CC
public:
{
UF(int n)
private:
{
bool *marked;
id=new int[n];
int *id;
for(int i=0;i<n;i++)
int cou=0;
id[i]=i;
void dfs(graph G, int v)
}
{
int root(int i)
marked[v]=true;
{
id[v]=cou;
while(i!=id[i])
for(int &w : G.con(v))
{
{
id[i]=id[id[i]];
if(!marked[w])
i=id[i];
dfs(G,w);
}
}
return i;
}
}
bool iscon(int p, int q)
public:
{
CC(graph G)
return (root(p)==root(q));
{
}
marked = new bool[G.v()];
void join(lli p, lli q)
id = new int[G.v()];
// join the two components (root to root)
for(int v=0;v<G.v();v++)
{
marked[v]=false;
id[root(p)]=id[root(q)];
for(int v=0;v<G.v();v++)
}
{
};
if(!marked[v])
Dijkstra (V^2)
{
int minDistance(int dist[], bool sptSet[])
dfs(G,v);
{
cou++;
int min = INT_MAX, min_index;
}
for (int v = 0; v < V; v++)
}
if (sptSet[v] == false && dist[v] <= min)
}
min = dist[v], min_index = v;
int total()
return min_index;
{
}
return cou;
}
void dijkstra ( int graph[V][V] , int src )
int cid(int v)
{
{
int dist[V] ;
return id[v];
bool sptSet[V] ;
}
for ( int i = 0 ; i < V ; i++ ) {
bool connected(int v,int w)
dist[i] = INT_MAX;
{
sptSet[i] = false ;
return id[v]==id[w];
}
}
dist[src] = 0 ;
};