Hamming Distance
Problem Statement :
You are given a string , consisting of small latin letters 'a' and 'b'. You are also given queries to process. The queries are as follows: C : all the symbols in the string, starting at the , ending at the become equal to ; S : swap two consecutive fragments of the string, where the first is denoted by a substring starting from ending at and the second is denoted by a substring starting at ending at ; R : reverse the fragment of the string that starts at the symbol and ends at the one; W : output the substring of the string that starts at the symbol and ends at the one; H : output the Hamming distance between the consecutive substrings that starts at and respectively and have the length of . Everything is 1-indexed here. Input Format The first line of input contains a single integer the length of the string. The second line contains the initial string itself. The third line of input contains a single integer the number of queries. Then, there are lines, each denotes a query of one of the types above. Output Format For each query of the type W or the type H output an answer on the separate line of output.
Solution :
Solution in C :
In C :
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
void HandleC(char *S, int N) {
int l, r, ch;
scanf ("%d %d %c\n", &l, &r, (char *)&ch);
l--;
r--;
while (l <= r) {
S[l] = ch;
l++;
}
}
char tS[500001];
void HandleS(char *S, int N) {
int l1, l2, r1, r2, len1, len2, end=0;
int i, l, r;
scanf ("%d %d %d %d\n", &l1, &r1, &l2, &r2);
l1--;
l2--;
r1--;
r2--;
int indices[4][2] = {
{l2, r2+1}, {r1+1,l2}, {l1, r1+1}, {r2+1, N+1}
};
strncpy(tS+l1, S+l1, N-l1);
end = l1;
for (int i = 0; i < 4; i++){
int l = indices[i][0], r = indices[i][1];
if (l < r) {
strncpy(S+end, tS+l, r-l+1);
}
end += r - l;
}
/*
len1 = r1 - l1 + 1;
len2 = r2 - l2 + 1;
memcpy(tS, &S[l1], l2-l1);
memcpy(&S[l1], &S[l2], len2);
memcpy(&S[l1+len2], &tS[len1-1], (l2-l1)-len1);
memcpy(&S[l1+len2+l2-l1-len1], tS, len1);
*/
}
void HandleR(char *S, int N) {
int l, r, temp;
scanf ("%d %d\n", &l, &r);
l--;
r--;
while (l <= r) {
temp = S[l];
S[l] = S[r];
S[r] = temp;
l++;
r--;
}
}
void HandleW(char *S, int N) {
int l, r;
scanf ("%d %d\n", &l, &r);
l--;
r--;
while (l <= r) {
printf ("%c", S[l]);
l++;
}
printf ("\n");
}
void HandleH(char *S, int N) {
int l1, l2, len, hd = 0;
scanf ("%d %d %d\n", &l1, &l2, &len);
l1--;l2--;
while (len) {
if (S[l1] != S[l2])
hd++;
len--;
l1++;
l2++;
}
printf ("%d\n", hd);
}
int main() {
int N, M;
int ch;
char S[50001];
scanf ("%d\n%s\n%d\n", &N, S, &M);
while (M) {
scanf("%c ", (char *)&ch);
switch (ch) {
case 'C':
HandleC(S, N);
break;
case 'S':
HandleS(S, N);
break;
case 'R':
HandleR(S, N);
break;
case 'W':
HandleW(S, N);
break;
case 'H':
HandleH(S, N);
break;
default:
break;
}
M--;
}
return 0;
}
Solution in C++ :
In C ++ :
#include <bits/stdc++.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define RS(X) scanf("%s", (X))
#define CASET int ___T, case_n = 1; scanf("%d ", &___T); while (___T-- > 0)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
typedef long long LL;
using namespace std;
const int LEN = 20;
const int BOUND = 1<<LEN;
int rev[BOUND],bit_cnt[BOUND];
int ONES;
void init(){
REP(i,LEN)ONES|=1<<i;
REP(i,BOUND){
bit_cnt[i]=bit_cnt[i>>1]+(i&1);
int tmp=i;
REP(j,LEN){
rev[i]<<=1;
rev[i]|=tmp&1;
tmp>>=1;
}
}
}
int a[50010];
char s[50010];
int tmp1[50010],tmp2[50010],tmp3[50010];
void get(int tmp[],int st,int len){
if(!len){
tmp[0]=0;
return;
}
int w=len/LEN;
int r=st%LEN;
int x=st/LEN;
int mask1=(1<<r)-1;
int mask2=(1<<LEN)-1-mask1;
REP(i,w){
tmp[i]=((a[x+i]&mask2)>>r)|((a[x+i+1]&mask1)<<(LEN-r));
}
r=len-LEN*w;
tmp[w]=0;
REP(i,r){
if((a[(st+w*LEN+i)/LEN]>>((st+w*LEN+i)%LEN))&1)
tmp[w]|=1<<i;
}
}
void put(int tmp[],int st,int len){
if(!len)return;
int w=len/LEN;
int r=st%LEN;
int x=st/LEN;
int mask1=(1<<r)-1;
int mask2=(1<<LEN)-1-mask1;
int mask3=(1<<(LEN-r))-1;
int mask4=(1<<LEN)-1-mask3;
REP(i,w){
a[x+i]&=mask1;
a[x+i]|=(tmp[i]&mask3)<<r;
a[x+i+1]&=mask2;
a[x+i+1]|=(tmp[i]&mask4)>>(LEN-r);
}
r=len-LEN*w;
int xx=(st+w*LEN)/LEN;
int yy=(st+w*LEN)%LEN;
REP(i,r){
if(((tmp[w]>>i)&1) != ((a[xx]>>yy)&1))
a[xx]^=1<<yy;
yy++;
if(yy==LEN){
xx++;
yy=0;
}
}
}
int main(){
init();
DRII(N,M);
RS(s);
int sn=LEN(s);
{
int x=0,y=0;
REP(i,sn){
if(s[i]=='b')a[x]|=1<<y;
y++;
if(y==LEN){
x++;
y=0;
}
}
}
DRI(Q);
while(Q--){
//REP(i,5)printf("%d",a[i]);
//puts("");
char c[4];
RS(c);
if(c[0]=='C'){
DRII(ll,rr);
ll--;rr--;
int st=(ll+LEN-1)/LEN,ed=(rr+1)/LEN;
RS(c);
int len=(rr-ll+LEN)/LEN;
if(c[0]=='a'){
REP(i,len)tmp1[i]=0;
}
else{
REP(i,len)tmp1[i]=ONES;
}
put(tmp1,ll,rr-ll+1);
}
else if(c[0]=='S'){
DRII(ll1,rr1);
DRII(ll2,rr2);
ll1--;rr1--;ll2--;rr2--;
get(tmp1,ll1,rr1-ll1+1);
get(tmp2,rr1+1,ll2-1-rr1);
get(tmp3,ll2,rr2-ll2+1);
// printf("[[%d%d]]\n",tmp1[0],tmp1[1]);
//printf("[[%d]]\n",tmp3[0]);
put(tmp3,ll1,rr2-ll2+1);
put(tmp2,ll1+rr2-ll2+1,ll2-1-rr1);
put(tmp1,ll1+rr2-rr1,rr1-ll1+1);
}
else if(c[0]=='R'){
DRII(ll,rr);
ll--;rr--;
int len=rr-ll+1;
get(tmp1,ll,len);
//REP(i,5)printf("[%d]",tmp1[i]);
if(len%LEN==0){
int w=len/LEN;
REP(i,w)tmp2[i]=rev[tmp1[w-i-1]];
}
else{
int w=len/LEN;
int r=len%LEN;
int mask1=(1<<r)-1;
int mask2=(1<<LEN)-1-mask1;
REP(i,w)tmp2[i]=rev[((tmp1[w-i]&mask1)<<(LEN-r))|((tmp1[w-i-1]&mask2)>>r)];
tmp2[w]=0;
REP(i,r)
if((tmp1[0]>>(r-i-1))&1)tmp2[w]|=1<<i;
}
put(tmp2,ll,len);
}
else if(c[0]=='W'){
DRII(ll,rr);
ll--;
int x=ll/LEN;
int y=ll%LEN;
REPP(i,ll,rr){
int now=(a[x]>>y)&1;
if(now)putchar('b');
else putchar('a');
y++;
if(y==LEN){
x++;
y=0;
}
}
puts("");
}
else if(c[0]=='H'){
DRIII(st1,st2,len);
st1--;st2--;
get(tmp1,st1,len);
get(tmp2,st2,len);
len=(len+LEN-1)/LEN;
int an=0;
REP(i,len)an+=bit_cnt[tmp1[i]^tmp2[i]];
printf("%d\n",an);
}
}
return 0;
}
Solution in Java :
In Java :
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public class Hamming {
public static void main(String[] args) throws IOException, InterruptedException {
Hamming solution = new Hamming(System.in);
// Thread.sleep(10000);
solution.run();
}
private class Scanner {
public final byte[] bytes;
public final int length;
public int pos = 0;
private Scanner(InputStream in) throws IOException {
bytes = new byte[2026000];
int read;
int pos = 0;
while((read = in.read(bytes, pos, bytes.length - pos)) != -1)
pos += read;
this.length = pos;
}
private int nextInt() {
int i = 0;
int d;
while((d = (bytes[pos++] - '0')) >= 0 && d <= 9) {
i = i*10 + d;
}
while(true) {
switch(bytes[pos]) {
case '\r':
case '\n':
case ' ':
pos++;
continue;
default:
// System.out.println("nextInt: " + i);
return i;
}
}
}
private String nextLine() {
int start = pos;
while(bytes[pos] != '\r' && bytes[pos] != '\n')
pos++;
int len = pos - start;
skipNewline();
// System.out.println("nextLine pos " + pos + ": " + new String(bytes, start, len));
return new String(bytes, start, len);
}
private void skipNewline() {
while(true) {
switch(bytes[pos]) {
case '\r':
case '\n':
pos++;
continue;
default:
return;
}
}
}
}
private final Scanner scan;
private final int N;
private final int M;
private final CharArraySolution solution;
private Hamming(InputStream in) throws IOException {
scan = new Scanner(in);
N = scan.nextInt();
solution = new CharArraySolution(scan.nextLine());
M = scan.nextInt();
}
private void run() {
for(int m=0; m<M; m++) {
switch (scan.bytes[scan.pos++]) {
case 'C':
scan.pos++;
solution.set(scan.nextInt(), scan.nextInt(), scan.bytes[scan.pos++]);
scan.skipNewline();
break;
case 'S':
scan.pos++;
solution.swap(scan.nextInt(), scan.nextInt(), scan.nextInt(), scan.nextInt());
break;
case 'R':
scan.pos++;
solution.reverse(scan.nextInt(), scan.nextInt());
break;
case 'W':
scan.pos++;
solution.write(scan.nextInt(), scan.nextInt());
break;
case 'H':
scan.pos++;
solution.hamming(scan.nextInt(), scan.nextInt(), scan.nextInt());
break;
}
}
System.out.print(solution.toString());
}
private class CharArraySolution {
private final int N;
private final char[] forward;
private final char[] reverse;
private final char[] as;
private final char[] bs;
private final char[] buf;
private final char[] out;
private int outpos = 0;
private CharArraySolution(String string) {
char[] chars = string.toCharArray();
N = chars.length;
forward = new char[N+1];
System.arraycopy(chars, 0, forward, 1, N);
reverse = new char[N+1];
for(int i=1; i<=N; i++) {
reverse[i] = forward[N-i+1];
}
as = new char[N+1];
Arrays.fill(as, 'a');
bs = new char[N+1];
Arrays.fill(bs, 'b');
// write(1,N);
buf = new char[N+1];
out = new char[2000000];
}
private void set(int l, int r, byte c) {
// System.out.println("set " + l + " " + r + " " + c);
int len = r-l+1;
if(c == 'a') {
System.arraycopy(as, 0, forward, l, len);
l = N-r+1;
System.arraycopy(as, 0, reverse, l, len);
} else {
System.arraycopy(bs, 0, forward, l, len);
l = N-r+1;
System.arraycopy(bs, 0, reverse, l, len);
}
// write(1,N);
}
private void swap(int l1, int r1, int l2, int r2) {
// System.out.println("swap " + l1 + " " + r1 + " " + l2 + " " + r2);
int len1 = r1-l1+1;
int len2 = r2-l2+1;
int lenm = l2-r1-1;
if(len1 > len2) {
System.arraycopy(forward, l1, buf, 0, len1);
System.arraycopy(forward, l2, forward, l1, len2);
System.arraycopy(forward, r1+1, forward, l1+len2, lenm);
System.arraycopy(buf, 0, forward, l1+len2+lenm, len1);
int oldl1 = l1;
int oldr1 = r1;
l1 = N-r2+1;
r1 = N-l2+1;
l2 = N-oldr1+1;
r2 = N-oldl1+1;
int oldlen1 = len1;
len1 = len2;
len2 = oldlen1;
System.arraycopy(reverse, l2, buf, 0, len2);
System.arraycopy(reverse, l1, reverse, r2-len1+1, len1);
System.arraycopy(reverse, r1+1, reverse, r2-len1-lenm+1, lenm);
System.arraycopy(buf, 0, reverse, l1, len2);
} else {
System.arraycopy(forward, l2, buf, 0, len2);
System.arraycopy(forward, l1, forward, r2-len1+1, len1);
System.arraycopy(forward, r1+1, forward, r2-len1-lenm+1, lenm);
System.arraycopy(buf, 0, forward, l1, len2);
int oldl1 = l1;
int oldr1 = r1;
l1 = N-r2+1;
r1 = N-l2+1;
l2 = N-oldr1+1;
r2 = N-oldl1+1;
int oldlen1 = len1;
len1 = len2;
len2 = oldlen1;
System.arraycopy(reverse, l1, buf, 0, len1);
System.arraycopy(reverse, l2, reverse, l1, len2);
System.arraycopy(reverse, r1+1, reverse, l1+len2, lenm);
System.arraycopy(buf, 0, reverse, l1+len2+lenm, len1);
}
// write(1,N);
}
private void reverse(int l, int r) {
// System.out.println("reverse " + l + " " + r);
int len = r-l+1;
System.arraycopy(forward, l, buf, 0, len);
System.arraycopy(reverse, N-r+1, forward, l, len);
System.arraycopy(buf, 0, reverse, N-r+1, len);
// write(1,N);
}
private void write(int l, int r) {
int len = r-l+1;
System.arraycopy(forward, l, out, outpos, len);
outpos += len;
out[outpos++] = '\n';
// System.out.println(Arrays.copyOfRange(reverse, N-r+1, N-l+2));
}
private void hamming(int p1, int p2, int l) {
// System.out.println("ham " + p1 + " " + p2 + " " + l);
int c = 0;
for(int i=0; i<l; i++) {
if(forward[p1++] != forward[p2++])
c++;
}
int bufpos = 10;
do {
buf[bufpos--] = (char)('0' + (c%10));
c /= 10;
} while(c>0);
System.arraycopy(buf, bufpos+1, out, outpos, 10 - bufpos);
outpos += 10 - bufpos;
out[outpos++] = '\n';
}
public String toString() {
return new String(out, 0, outpos);
}
}
}
Solution in Python :
In Python3 :
L = int(input())
S = input().strip()
M = int(input())
x = 0
z = 1
for c in S:
if c == 'b':
x += z
z *= 2
x += z
def prnt(n):
i = 1
s = ''
while i < z:
s += 'ab'[i & n > 0]
i *= 2
print(s)
#prnt(x)
for i in range(M):
e = input().strip()
#e = 'S 1 2 3 4'
q = e.split()
a = q[0]
if a in 'CR':
i, j = map(lambda c: int(c)-1, q[1:3])
mask1 = (1 << i) - 1
mask2 = (1 << (j+1)) - 1
mask3 = (z - 1) ^ mask2
mask2 ^= mask1
y = x & (mask1 | mask3)
if a == 'C' and q[3] == 'b':
y |= mask2
elif a == 'R':
m = (x & mask2) >> i
m |= (mask2 >> i) + 1
rev = int(bin(m)[2:][::-1], base=2) >> 1
y |= rev << i
x = y
#prnt(x)
elif a == 'S':
i, j, t, u = map(lambda c: int(c)-1, q[1:])
mask5 = z - 1
mask4 = (1 << (u+1)) - 1
mask5 ^= mask4
mask3 = (1 << t) - 1
mask4 ^= mask3
mask2 = (1 << (j+1)) - 1
mask3 ^= mask2
mask1 = (1 << i) - 1
mask2 ^= mask1
y = x & mask1
y |= (x & mask4) >> (t - i)
#mask4 >>= t - i
p = (x & mask3)
p |= (x & mask2) << (t - i)
k = u + 1 - (t-i)
if k <= j:
p >>= j - k + 1
else:
p <<= k - j - 1
y |= p
y |= x & mask5
x = y
#prnt(x)
#break
elif a == 'W':
i, j = map(lambda c: int(c)-1, q[1:])
k = 1 << i
m = 1 << j
r = ''
while k <= m:
r += 'ab'[k & x > 0]
k <<= 1
print(r)
elif a == 'H':
#prnt(x)
i, j, L = map(int, q[1:])
i -= 1
j -= 1
msk = [0, 0]
for t, u in enumerate([i, j]):
msk[t] = (1 << (u + L)) - 1
msk[t] ^= (1 << u) - 1
t = (x & msk[0]) >> i
u = (x & msk[1]) >> j
print(bin(t^u).count('1'))
View More Similar Problems
Array Pairs
Consider an array of n integers, A = [ a1, a2, . . . . an] . Find and print the total number of (i , j) pairs such that ai * aj <= max(ai, ai+1, . . . aj) where i < j. Input Format The first line contains an integer, n , denoting the number of elements in the array. The second line consists of n space-separated integers describing the respective values of a1, a2 , . . . an .
View Solution →Self Balancing Tree
An AVL tree (Georgy Adelson-Velsky and Landis' tree, named after the inventors) is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. We define balance factor for each node as : balanceFactor = height(left subtree) - height(righ
View Solution →Array and simple queries
Given two numbers N and M. N indicates the number of elements in the array A[](1-indexed) and M indicates number of queries. You need to perform two types of queries on the array A[] . You are given queries. Queries can be of two types, type 1 and type 2. Type 1 queries are represented as 1 i j : Modify the given array by removing elements from i to j and adding them to the front. Ty
View Solution →Median Updates
The median M of numbers is defined as the middle number after sorting them in order if M is odd. Or it is the average of the middle two numbers if M is even. You start with an empty number list. Then, you can add numbers to the list, or remove existing numbers from it. After each add or remove operation, output the median. Input: The first line is an integer, N , that indicates the number o
View Solution →Maximum Element
You have an empty sequence, and you will be given N queries. Each query is one of these three types: 1 x -Push the element x into the stack. 2 -Delete the element present at the top of the stack. 3 -Print the maximum element in the stack. Input Format The first line of input contains an integer, N . The next N lines each contain an above mentioned query. (It is guaranteed that each
View Solution →Balanced Brackets
A bracket is considered to be any one of the following characters: (, ), {, }, [, or ]. Two brackets are considered to be a matched pair if the an opening bracket (i.e., (, [, or {) occurs to the left of a closing bracket (i.e., ), ], or }) of the exact same type. There are three types of matched pairs of brackets: [], {}, and (). A matching pair of brackets is not balanced if the set of bra
View Solution →