Bob gave Alex a string s consisting of lowercase English letters of length n. He then asked Alex to construct a new string s1 using the characters of s such that no two characters appear more than k times consecutively. It is not mandatory to use all characters from s.
Help Alex find the lexicographically largest possible string s1.
Input Format
First line letters integers n and k.
Second line contains string s of length n.
Output Format
Print the lexicographically largest string s1.
Sample Input 0
7 3
ddybydd
Sample Output 0
yydddbd
Explanation 0
No letter appears more than 3 times consecutively and also the string is lexicographically largest.
There are N cities (1, 2,......., N) and M roads and the cities are connected to other cities by those roads. Terrorists have planted bombs in every city. Each bomb will explode one after the other. First bomb in city1 will explode, then city2 and so on.
Each explosion will destroy the city and the roads which are connected to it.
For every explosion, you need to return the number of connected components of cities.
Input Format
Input is given from Standard Input in the following format:
N M
A1 B1
A2 B2
-
-
-
AM BM
(Ai, Bi represents City number)
Constraints
1 <= N <= 200000
0 <= M <= min(200000,(N(N-1))/2)
1 <= Ai, All values are in input are integers
Output Format
Print N lines.
The i-th line should contain the number of connected components when a city is exploded.
Sample Input 0
6 7
1 2
1 4
1 5
2 4
2 3
3 5
3 6
Sample Output 0
1
2
3
2
1
0
Explanation 0
You are given two arrays a and b. You draw lines by connecting a[i] with b[j] where a[i]==b[j]. You need to find maximum lines you can draw without crossing each other. You are expected to solve this problem in approximately O(n^2) time.
Most problems that require deleting edges or nodes from a graph can be solved simply by processing the queries offline in the reverse order. Suppose that we start with a graph having 0 nodes and 0 edges. Now we add the nodes (and the edges corresponding to them) in the reverse order of their deletion, i.e. starting from N down to 1. We can simply use a DSU or Union Find Data Structure to simulate this process and hence answer the queries in the reverse order.
class DSU: //DSU implemntation
parent = [0]*N
size = [0]*N
components = 0
make_node(x): //function to create a new node
components++
parent[x] = x
size[x] = 1
is_active(x):
return size[x] != 0
find(x): //find(x) returns the representative element of the set containing x
return parent[x] = (parent[x] == x) ? x : find(parent[x])
merge(a,b):
a = find(a)
b = find(b)
if(a == b) return //if the representative elements are same, these nodes are already connected, hence we return
components-- //otherwise we have merged two components and hence the no of components reduces by 1
if(size[b] > size[a]) swap(a,b)
size[a] += size[b]
parent[b] = a
solve(N, Edges)
d = DSU(N)
ans = []
for node from N to 1:
d.make_node(node)
for nbr in Edges[node]:
if(d.is_active(nbr)):
d.merge(node,nbr)
ans.append(d.components)
ans.reverse()
return ans
Overview
Solution
Code
ll n, k;
cin >> n >> k;
string s;
cin >> s;
vector<ll> freq(26, 0);
for (ll i = 0; i < n; i++)
{
freq[s[i] - 'a']++;
}
set<pair<char, ll>> se;
char c = 'a';
for (ll i = 0; i < 26; i++)
{
if (freq[i])
{
se.insert({c, freq[i]});
}
c++;
}
string s1 = "";
ll cnt_char = 0;
while (se.size())
{
auto it = se.end();
it--;
if (cnt_char < k)
{
s1 += (*it).ff;
if ((*it).ss > 1)
{
se.insert({(*it).ff, (*it).ss - 1});
cnt_char++;
}
else
{
cnt_char = 0;
}
se.erase(it);
}
else
{
cnt_char = 0;
if (se.size() > 1)
{
it--;
s1 += (*it).ff;
if ((*it).ss > 1)
{
se.insert({(*it).ff, (*it).ss - 1});
}
se.erase(it);
}
else
{
break;
}
}
}
cout << s1 << endl;
return;
SOLUTION TO Q2
#include <bits/stdc++.h>
using namespace std;
#define int long long
vector<int> sz;
vector<int> par;
int comp = 0;
void node(int x)
{
comp++;
par[x] = x;
sz[x] = 1;
}
bool active(int x)
{
return sz[x] != 0;
}
int find(int x)
{
if (par[x] == x)
return x;
else
return find(par[x]);
}
void merge(int u, int v)
{
int x = find(u);
int y = find(v);
if (x == y)
{
return;
}
comp--;
if (sz[y] > sz[x])
swap(x, y);
sz[x] += sz[y];
par[y] = x;
return;
}
int32_t main()
{
int n, m;
cin >> n >> m;
par.resize(n, 0);
sz.resize(n, 0);
vector<int> adj[n];
for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
u--;
v--;
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> ans;
for (int i = n - 1; i >= 0; i--)
{
ans.push_back(comp);
node(i);
for (auto it : adj[i])
{
if (active(it))
merge(i, it);
}
}
reverse(ans.begin(), ans.end());
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
class disjoint
{
private:
int nodes;
vector<int> parent,size;
public:
disjoint(int n)
{
nodes=n;
parent.resize(nodes);
for(int i=0;i<nodes;i++) parent[i]=i;
size.resize(nodes,1);
}
int findpar(int x)
{
if(x==parent[x]) return x;
return parent[x]=findpar(parent[x]);
}
void join(int x,int y)
{
int p1=parent[x],p2=parent[y];
if(size[p1]>size[p2])
{
size[p1]+=size[p2];
parent[p2]=parent[p1];
}
else
{
size[p2]+=size[p1];
parent[p1]=parent[p2];
}
}
};
int main() {
int n,m;
cin>>n>>m;
vector<vector<int>> graph(n);
disjoint dsu(n);
int components=0;
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
//ensuring 0 based indexing.
if(x<y)
{
graph[x-1].push_back(y-1);
}
else
{
graph[y-1].push_back(x-1);
}
}
stack<int> st;
st.push(0);
for(int new_node=n-1;new_node>=0;new_node--)
{
components++;
for(auto exit_node: graph[new_node])
{
if(dsu.findpar(exit_node)!=dsu.findpar(new_node))
{
components--;
}
dsu.join(exit_node,new_node);
}
if(new_node!=0)
st.push(components);
}
while(!st.empty())
{
cout<<st.top()<<endl;
st.pop();
}
return 0;
}