vl conv(vl a, vl b) { int s = sz(a)+sz(b)-1, L = get(s), n = 1<<L; if (s <= 0) return {}; if (s <= 200) return brute(a,b); a.resize(n); a = ntt(a); b.resize(n); b = ntt(b); F0R(i,n) a[i] = a[i]*b[i] % mod; a = ntt_rev(a); a.resize(s); return a; }
void dijkstra(int s) { dist.assign(n+1, INF); dist[s] = 0LL; par.assign(n+1, -1); priority_queue <pp, vector <pp>, greater <pp> > PQ; PQ.push(pp(dist[s], s)); while (!PQ.empty()) { pp front = PQ.top(); PQ.pop(); long long int d = front.first; int u = front.second; if (d > dist[u]) continue; for (int j = 0; j < (int)AdjList[u].size(); j++) { pp v = AdjList[u][j]; if (dist[v.first] > dist[u] + v.second) { dist[v.first] = dist[u] + v.second; par[v.first] = u; PQ.push(pp(dist[v.first], v.first)); } } } }
vl ntt_rev(vl& a) { vl res = ntt(a); ll in = inv(a.size()); F0R(i,sz(res)) res[i] = res[i]*in % mod; reverse(res.begin() + 1, res.end()); return res; }
int lis(const vl& in, vi& liss, vi& parents) { // position j gives index of the last element in "best" // known lis of length j (where best means ends in // smallest element) vi length_idx(in.size() + 1, -1); // position i gives the immediate predecessor of element i // in best known lis parents.resize(in.size(), -1); // gives the length of the best known lis ending in pos i liss.resize(in.size(), -1); // best known length int L = 0; for(int i = 0; i < in.size(); ++i) { // binary search for largest pos j <= L s.t. // in[length_idx[j]] < in[i] // i.e. the lis we can append in[i] onto int low = 1, high = L; while(low <= high) { int mid = ceil((low+high)/2); if(in[length_idx[mid]] < in[i]) low = mid+1; else high = mid-1; } // low is length of lis ending in in[i] parents[i] = length_idx[low-1]; length_idx[low] = i; liss[i] = low; // update best known length L = max(L, low); } return L; }
void unionEquals(vl & G, DisjointSet &ds, CmpByMask cmp) { for (uint i = 0; i < G.size() - 1; ++i) { /* if previous less than next */ if (cmp(G[i], G[i + 1])) { continue; } /* two adjacent nodes are equal */ /* check if they belong to different component and union them */ /* BUG: keep index in G */ if (ds.findSet(i) != ds.findSet(i + 1)) { ds.unionNodes(i, i + 1); } } }