Download as pdf or txt
Download as pdf or txt
You are on page 1of 13

Cheat Sheet For BLPC 2016

Basics
#include <vector>
#include <list>
#include <map>
#include <set>
1
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#define REP(X, Y) for (int (X) = 0; (X) < (Y); ++(X))
#define FOR(X, Y, Z) for (int (X) = (Y); (X) <= (Z); ++(X))
#define RESET(C, V) memset(C, V, sizeof(C))
#define isOn(S, j) (S & (1 << j))
#define setBit(S, j) (S |= (1 << j))
#define clearBit(S, j) (S &= ~(1 << j))
#define toggleBit(S, j) (S ^= (1 << j))
#define lowBit(S) (S & (-S))
#define setAll(S, n) (S = (1 << n) - 1)
#define modulo(S, N) ((S) & (N - 1)) // returns S % N, where N is a power of 2
#define isPowerOfTwo(S) (!(S & (S - 1)))
#define nearestPowerOfTwo(S) ((int)pow(2.0, (int)((log((double)S) / log(2.0)) + 0.5)))
#define turnOffLastBit(S) ((S) & (S - 1))
#define turnOnLastZero(S) ((S) | (S + 1))
#define turnOffLastConsecutiveBits(S) ((S) & (S + 1))
#define turnOnLastConsecutiveZeroes(S) ((S) | (S - 1))
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef vector<ii> vii;

Union Find
class UnionFind {
private:
vi p, rank, setSize;
int numSets;
public:
UnionFind(int N) {
setSize.assign(N, 1); numSets = N; rank.assign(N, 0);
p.assign(N, 0); for (int i = 0; i < N; i++) p[i] = i; }
int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
void unionSet(int i, int j) {
if (!isSameSet(i, j)) { numSets--;
int x = findSet(i), y = findSet(j);
if (rank[x] > rank[y]) { p[y] = x; setSize[x] += setSize[y]; }
else { p[x] = y; setSize[y] += setSize[x];
if (rank[x] == rank[y]) rank[y]++; } } }
int numDisjointSets() { return numSets; }
int sizeOfSet(int i) { return setSize[findSet(i)]; }
};
Fenwick Tree
class FenwickTree{
private:
vi ft;
public:
FenwickTree(int n) { ft.assign(n+1, 0); }
2
int rsq(int b) { int sum=0; for(; b; b -= LSOne(b)) sum += ft[b]; return sum; }
int rsq(int a, int b) { return rsq(b) – (a == 1 ? 0 : rsq(a-1)); }
void adjust(int k, int v) { for(; k<(int)ft.size(); k+=LSOne(k)) ft[k]+=v; } };

Depth First Search


vi dfs_num;
void dfs(int u) {
dfs_num[u] = VISITED;
for(int j = 0; j < (int)AdjList[u].size(); j++) {
ii v = AdjList[u][j];
if(dfs_num[v.first] == UNVISITED) dfs(v.first); } }

Breadth First Search


vi d(V, INF); d[s]=0;
queue<int> q; q.push(s);
while(!q.empty()) {
int u=q.front(); q.pop();
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v=AdjList[u][j];
if(d[v.first] == INF) { d[v.first] = d[u] + 1; q.push(v.first); } } }

Shortest Path (Dijkstra)


vi dist(NI+1, INF); dist[s] = 0; memset(edgeTo, -1, sizeof edgeTo);
edgeTo[s] = s; priority_queue< ii, vector<ii>, greater<ii> > pq;
pq.push(ii(0, s));
while (!pq.empty()) {
ii front = pq.top();pq.pop(); int d = front.first, u = front.second;
if (d > dist[u]) continue;
for (int j = 0; j < (int)AdjList[u].size(); j++) {
ii v = AdjList[u][j];
if (dist[u] + v.second < dist[v.first]) {
dist[v.first] = dist[u] + v.second; edgeTo[v.first] = u;
pq.push(ii(dist[v.first], v.first)); } } }

Bellman Ford
int s = 1;
vi dist(N+1, INF); dist[s]=0;
for(int i = 1; i < N; i++) for(int u = 1; u < N+1; u++)
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v = AdjList[u][j];
dist[v.first] = min(dist[v.first], dist[u] + v.second); }
bool hasNegativeCycle = false;
for(int u = 1; u < N+1; u++)
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v = AdjList[u][j]; if(dist[v.first] > dist[u] + v.second)
hasNegativeCycle = true; } printf(“”);
Topological Sort
vi ts;
void dfs2(int u){
dfs_num[u] = VISITED;
for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v = AdjList[u][j];
3
if(dfs_num[v.first] == UNVISITED)
dfs2(v.first);
}
ts.push_back(u);
}
-----------------------------------------------------------------------------------
int i, j, N, M, V, W, P, dfsNumberCounter, numSCC;
vector<vii> AdjList, AdjListT;
vi dfs_num, dfs_low, S, S_copy, visited;

Kosaraju
void Kosaraju(int u, int pass) {
dfs_num[u] = 1; vii neighbor;
if(pass==1) neighbor = AdjList[u];
else neighbor = AdjListT[u];
for(int j = 0; j < (int)neighbor.size(); j++) {
ii v = neighbor[j];
if(dfs_num[v.first] == DFS_WHITE) Kosaraju(v.first, pass);
}
S.push_back(u); }
Tarjan
void tarjanSCC(int u) {
dfs_low[u] = dfs_num[u] = dfsNumberCounter++; S.push_back(u);
visited[u] = 1; for(int j = 0; j < (int)AdjList[u].size(); j++){
ii v= AdjList[u][j];
if(dfs_num[v.first] == DFS_WHITE) tarjanSCC(v.first);
if(visited[v.first]) dfs_low[u] = min(dfs_low[u], dfs_low[v.first]); }
if(dfs_low[u] == dfs_num[u]) {
++numSCC;
while(1) { int v=S.back(); S.pop_back(); visited[v]=0; if(u==v) break; } } }
-----------------------------------------------------------------------------------

Kruskal
vector< pair<int, ii> > EdgeList;
sort(EdgeList.begin(), EdgeList.end());
mstnew=0; UnionFind UF(N);
for(int I = 0; i < M+K; i++) {
pair<int, ii> nextEdge = EdgeList[i];
if(!UF.isSameSet(nextEdge.second.first, nextEdge.second.second)) {
mstnew += nextEdg.1st;
UF.unionSet(nextEdge.second.first, nextEdge.second.first); } }
-----------------------------------------------------------------------------------

Longest Increasing / Decreasing Subsequence


unsigned long LDS[2005], LIS[2005];
void doLIS() {
LIS[0] = 1;
for(int i = n - 1; i >= 0; i--){ ul tmp = 1; for(int j = i + 1; j < n; j++) {
if(v[i] < v[j]){ tmp = max(tmp, LIS[j] + 1); } } LIS[i] = tmp; } }
void doLDS() {
LDS[0] = 1;
for(int i = n - 1; i >= 0; i--){ ul tmp = 1; for(int j = i + 1; j < n; j++) {
if(v[i] > v[j]){ tmp = max(tmp, LDS[j] + 1); } } LDS[i] = tmp; } }

Bytelandian Coins (Dynamic Programming)


map<int, ll> memo;
ll exchangeornot(int n){
if(n < 12) return n;
if(memo[n] != 0) return memo[n];
if(!(n % 2 == 0 || n % 3 == 0 || n % 4 == 0)){
memo[n] = exchangeornot(n-1);
}
else{
memo[n] = max(ll(n), exchangeornot(n/2) + exchangeornot(n/3) + exchangeornot(n/4));
}
return memo[n];
4
}
int main(){
ll input;
while(scanf("%d", &input) == 1){
cout << exchangeornot(input) << endl;
}
return 0;
}
Defense (Longest Increasing Subsequence)
int main(){
int tc;
int line = 0;
string s;
cin >> tc;
//untuk mengabaikan input blank line
getchar();
getline(cin, s);
while(tc--){
if(line != 0) cout << endl;
line = 1;
vector<int> height;
while(getline(cin, s)){
if(s.size() == 0) break;
height.push_back(atoi(s.c_str()));
}
//hitung jumlah input
int n = height.size();
//jika tidak ada input
if(n == 0){
printf("Max hits: 0\n");

}
//bagian dynamic programming-nya
//bisa dijadikan fungsi
vector<int> lis;
lis.push_back(1);
for(int i = 1; i < n; i++){
//nilai lis untuk nilai yang terkecil dari 0 s/d i adalah 1
int temp = 1;
//cek nilai sebelumnya
for(int j = i-1; j >= 0; j--){
//jika nilai sebelumnya lebih besar dari nilai ke i
if(height[i] > height[j]){
//ubah nilai lis
temp = max(temp, lis[j]+1);
}
}
//setelah dapat yang maksimal, tampung hasilnya
lis.push_back(temp);
}
//akhir bagian dynamic programming-nya
int max = 0;
int index = 0;
//mencari nilai lis maksimum dan indeksnya
for(int i = 0; i < n; i++){
if(lis[i] > max){
max = lis[i];
index = i;
}
}
printf("Max hits: %d\n", max);
stack<int> urutan;
urutan.push(height[index]);
max--;
for(int i = index-1; i >= 0; i--){
if(lis[i] == max){
urutan.push(height[i]);
max--;
5
if(max == 0) break;
}
}
while(!urutan.empty()){
printf("%d\n", urutan.top());
urutan.pop();
}
}
// cin >> tc;
return 0;
}

Freckles
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<double, double> dd;
const int INF = 999999999;
// Union Find Class
int main(){
int tc, point;
double x, y, mst_cost;
vector<dd> v;
vector<pair<double, ii> > EdgeList;
string buang;
scanf("%d", &tc);
while(tc--){
v.clear();
EdgeList.clear();
mst_cost = 0;
getline(cin, buang);
getline(cin, buang);
scanf("%d", &point);
while(point--){
cin >> x >> y;
v.push_back(dd(x, y));
}
for(int i = 0; i < v.size(); i++){
for(int j = i+1; j < v.size(); j++){
double w = sqrt((v[i].first-v[j].first)*(v[i].first-v[j].first) +
(v[i].second-v[j].second)*(v[i].second-v[j].second));
EdgeList.push_back(make_pair(w, ii(i+1, j+1)));
}
}
sort(EdgeList.begin(), EdgeList.end());
UnionFind UF(v.size());
for(int i = 0; i < EdgeList.size(); i++){
pair<double, ii> front = EdgeList[i];
if(!UF.isSameSet(front.second.first, front.second.second)){
mst_cost += front.first;
UF.unionSet(front.second.first, front.second.second);
}
}
printf("%.2f\n", mst_cost);
}
}

Genes
typedef pair<string, string> ss;
map<string, string> gen;
map<string, ss> parent;
set<string> name;
set<string> childlist;
set<string>::iterator iterset;
string findParent(string child){
if(gen[child] != "") return gen[child];
string p1 = findParent(parent[child].first);
string p2 = findParent(parent[child].second);
if(p1 == "dominant" && p2 == "dominant") return "dominant";
6
if(p1 == "dominant" && p2 == "recessive") return "dominant";
if(p1 == "dominant" && p2 == "non-existent") return "recessive";
if(p1 == "recessive" && p2 == "dominant") return "dominant";
if(p1 == "recessive" && p2 == "recessive") return "recessive";
if(p1 == "recessive" && p2 == "non-existent") return "non-existent";
if(p1 == "non-existent" && p2 == "dominant") return "recessive";
if(p1 == "non-existent" && p2 == "recessive") return "non-existent";
if(p1 == "non-existent" && p2 == "non-existent") return "non-existent";
}
int main(){
int line;
string str1, str2;
cin >> line;
while(line--){
cin >> str1 >> str2;
if(str2 == "dominant" || str2 == "recessive" || str2 == "non-existent"){
gen[str1] = str2;
name.insert(str1);
} else {
if(parent[str2].first == "") parent[str2].first = str1;
else parent[str2].second = str1;
childlist.insert(str2);
name.insert(str2);
}
}
iterset = childlist.begin();
for( ; iterset != childlist.end(); iterset++){
gen[*iterset] = findParent(*iterset);
}
iterset = name.begin();
for( ; iterset != name.end(); iterset++){
cout << *iterset << " " << gen[*iterset] << endl;
}
return 0;

Large KnapSack
using namespace std;
int dp[2][2000001] = {0};
int main(){
int k, n, v[505], w[505], index, prev;
scanf("%d %d", &k, &n);
for(int i = 1; i <= n; i++){
scanf("%d %d", &v[i], &w[i]);
}
for(int i = 1; i <= n; i++){
index = i % 2;
prev = (i - 1) % 2;
for(int j = 0; j <= k; j++){
if(j >= w[i]){
dp[index][j] = max(dp[prev][j], v[i] + dp[prev][j-w[i]]);
} else dp[index][j] = dp[prev][j];
}
/* for(int j = 0; j <= k; j++) printf("%d ", dp[0][j]);
printf("\n");
for(int j = 0; j <= k; j++) printf("%d ", dp[1][j]);
printf("\n");
system("pause"); */
}
printf("%d\n", dp[n%2][k]);
return 0;
}

Luggage (Dynamic Programming)


int dp[21][201];
int suits[21];
7
int total, n;
int knapsack(int suit, int take){
if(dp[suit][take] != -1) return dp[suit][take];
//kalau jumlah suit = jumlah semua suit, return selisih antara take dan ignore (ignore = total -
take)
//abs(take - (total - take) = abs(take - total + take) = abs(2*take - total)
if(suit == n - 1) return dp[suit][take] = abs(total - 2*take);
//recursive case
return dp[suit][take] = min(knapsack(suit+1, take+suits[suit]), knapsack(suit+1, take));
}

int main(){
int tc, suit, half, flag;
string input;
cin >> tc;
getline(cin, input);
while(tc--){
memset(dp, -1, sizeof(dp));
total = 0;
n = 0;
getline(cin, input);
istringstream iss(input);
while(iss >> suits[n]){
total += suits[n];
n++;
}
if(total % 2 == 1){
cout << "NO" << endl;
continue;
}
if(knapsack(0,0) == 0) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}

Lugage (Brute Force)


int bruteforce[1048576];
int main(){
int tc, suit, total, half, size, flag, possibility, part, take;
string input;
cin >> tc;
getline(cin, input);
while(tc--){
vector<int> v;
total = 0;
getline(cin, input);
istringstream iss(input);
while(iss >> suit){
v.push_back(suit);
total += suit;
}
if(total % 2 == 1){
cout << "NO" << endl;
continue;
}
size = v.size();
possibility = pow(2, size);
sort(v.begin(), v.end());
half = total / 2;
// jika koper terberat lebih besar half, langsung "NO"
if(v[size-1] > half){

}
cout << "NO" << endl;
continue;

// jika koper terberat sama dengan half, langsung "YES"


if(v[size-1] == half){
8
cout << "YES" << endl;
continue;
}
// jika koper terberat lebih kecil half tapi ditambah koper terkecil jadi
// lebih besar half, langsung "NO"
if(v[size-1] + v[0] > half){
cout << "NO" << endl;
continue;
}
// array tidak hanya di-set menjadi half semua, tapi langsung mempertimbangkan koper terberat
// setengah depan untuk "jika tidak ambil"
for(int i = 0; i <= possibility/2; i++) bruteforce[i] = half;
// setengah belakang untuk "jika ambil"
half -= v[size-1];
for(int i = possibility/2; i < possibility; i++) bruteforce[i] = half;
/* untuk lihat isi array setelah ambil koper terberat *
for(int j = 0; j < possibility; j++) cout << bruteforce[j] << " ";
cout << endl;
//*/
part = pow(2, size-2);
flag = 0;
for(int i = size-2; i >= 0; i--){
take = 1;
for(int j = 0; j < possibility; j++){
if(take % 2 == 0 && bruteforce[j] >= v[i]) bruteforce[j] -= v[i];
if(bruteforce[j] == 0){
flag = 1;
break;
}
if(j % part == part-1){
take++;
}
}
/* untuk lihat isi array setelah mempertimbangkan koper *
for(int j = 0; j < possibility; j++) cout << bruteforce[j] << " ";
cout << endl;
//*/
if(flag == 1) break;
part /= 2;
}
if(flag == 1) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}

Median (Priority_Queue)
int main(){
int in, size = 0;
priority_queue<int> maxpq;
priority_queue<int, vector<int>, greater<int> > minpq;
scanf("%d", &in);
maxpq.push(in);
size++;
printf("%d\n", in);
while(scanf("%d", &in) == 1){
maxpq.push(in);
size++;
if(size % 2 == 0){
minpq.push(maxpq.top());
maxpq.pop();
}
if(minpq.top() < maxpq.top()){

}
minpq.push(maxpq.top());
maxpq.pop();
maxpq.push(minpq.top());
minpq.pop();
9
if(size % 2 == 1) printf("%d\n", maxpq.top());
else printf("%d\n", (maxpq.top() + minpq.top()) / 2);
}
}

Potentiometer (Fenwick Tree)


typedef vector<int> vi;
#define LSOne(S) (S & (-S))
class FenwickTree {
private: vi ft;
public: FenwickTree(int n){ ft.assign(n + 1, 0); }
int rsq(int b){
int sum = 0;
for(; b; b -= LSOne(b)) sum += ft[b];
return sum;
}
int rsq(int a, int b){
return rsq(b) - (a == 1 ? 0 : rsq(a - 1));
}
void adjust(int k, int v){
for(; k < (int)ft.size(); k += LSOne(k)) ft[k] += v;
}
};
int main(){
int N, add, x, y, r, cases = 0;
char command[10];
while(scanf("%d", &N) && (N!=0)){
FenwickTree ft(N);
if(cases != 0) printf("\n");
printf("Case %d:\n", ++cases);
for(int i = 1; i <= N; i++){
scanf("%d", &add);
ft.adjust(i, add);
}
while(scanf("%s", &command) && !((command[0] == 'E') && (command[1] == 'N') && (command[2]
== 'D'))){
if(command[0] == 'S'){
cin >> x >> r;
int old = ft.rsq(x, x);
ft.adjust(x, r-old);
}
else if(command[0] == 'M'){
cin >> x >> y;
printf("%d\n", ft.rsq(x, y));
}
}
}
return 0;
}
STICKER (string)
#include <iostream>
#include <vector>
#include <cstring>
#define loop(i, n) for (int i = 0; i < n; i++)
10
using namespace std;

int main()
{
int R,C;
int i = 0;
int j = 0;
int k = 0;
int l = 0;
cin >> R >> C;
string output ="";
vector<string> v;
v.push_back(".####..#....");
v.push_back(".#...#.#....");
v.push_back(".#...#.#....");
v.push_back(".####..#....");
v.push_back(".#...#.#....");
v.push_back(".#...#.#....");
v.push_back(".####..#####");

fflush(stdin);
loop(i, R){
if(i==0){
string printc =".";
loop(l,C){
printc += "............";
}
printc += "\n";
output += printc;
}
loop(k,7){
string printr;
loop(j,C){
printr+= v.at(k);
}
printr+=".\n";
output+= printr;
}
string printc =".";
loop(l,C){
printc += "............";
}
printc += "\n";
output += printc;
}
cout << output;
}
Istringstream example

// istringstream::str
#include <string>
#include <iostream>
#include <sstream>
// std::string
// std::cout
// std::istringstream
11
int main () {
std::istringstream iss;
std::string strvalues = "32 240 2 1450";

iss.str (strvalues);

for (int n=0; n<4; n++)


{
int val;
iss >> val;
std::cout << val << '\n';
}
std::cout << "Finished writing the numbers in: ";
std::cout << iss.str() << '\n';
return 0;
}

Ostringstream Example
// ostringstream constructor
#include <iostream> // std::cout, std::ios
#include <sstream> // std::ostringstream

int main () {
std::ostringstream foo; // out
std::ostringstream bar (std::ostringstream::ate); // out|ate

foo.str("Test string");
bar.str("Test string");

foo << 101;


bar << 101;

std::cout << foo.str() << '\n';


std::cout << bar.str() << '\n';
return 0;
}

OUTPUT :
101t string
Test string101
SORT C++
// sort algorithm example
#include <iostream>
#include <algorithm>
#include <vector>
// std::cout
// std::sort
// std::vector
12
bool myfunction (int i,int j) { return (i<j); }

struct myclass {
bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33

// using default comparison (operator <):


std::sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33

// using function as comp


std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

// using object as comp


std::sort (myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80)

// print out content:


std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';

return 0;
}
OUTPUT :
myvector contains: 12 26 32 33 45 53 71 80
PQ and Q
// queue::front
#include <iostream>
#include <queue>

int main ()
// std::cout
// std::queue
13
{
std::queue<int> myqueue;

myqueue.push(77);
myqueue.push(16);

myqueue.front() -= myqueue.back(); // 77-16=61

std::cout << "myqueue.front() is now " << myqueue.front() << '\n';

std::priority_queue<int> mypq;
//inversed PQ
//priority_queue<int, vector<int>, std::greater<int> > first;

mypq.push(30);
mypq.push(100);
mypq.push(25);
mypq.push(40);

std::cout << "Popping out elements...";


while (!mypq.empty())
{
std::cout << ' ' << mypq.top();
mypq.pop();
}
std::cout << '\n';

return 0;
}

You might also like