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
Inserting a Node Into a Sorted Doubly Linked List
Given a reference to the head of a doubly-linked list and an integer ,data , create a new DoublyLinkedListNode object having data value data and insert it at the proper location to maintain the sort. Example head refers to the list 1 <-> 2 <-> 4 - > NULL. data = 3 Return a reference to the new list: 1 <-> 2 <-> 4 - > NULL , Function Description Complete the sortedInsert function
View Solution →Reverse a doubly linked list
This challenge is part of a tutorial track by MyCodeSchool Given the pointer to the head node of a doubly linked list, reverse the order of the nodes in place. That is, change the next and prev pointers of the nodes so that the direction of the list is reversed. Return a reference to the head node of the reversed list. Note: The head node might be NULL to indicate that the list is empty.
View Solution →Tree: Preorder Traversal
Complete the preorder function in the editor below, which has 1 parameter: a pointer to the root of a binary tree. It must print the values in the tree's preorder traversal as a single line of space-separated values. Input Format Our test code passes the root node of a binary tree to the preOrder function. Constraints 1 <= Nodes in the tree <= 500 Output Format Print the tree's
View Solution →Tree: Postorder Traversal
Complete the postorder function in the editor below. It received 1 parameter: a pointer to the root of a binary tree. It must print the values in the tree's postorder traversal as a single line of space-separated values. Input Format Our test code passes the root node of a binary tree to the postorder function. Constraints 1 <= Nodes in the tree <= 500 Output Format Print the
View Solution →Tree: Inorder Traversal
In this challenge, you are required to implement inorder traversal of a tree. Complete the inorder function in your editor below, which has 1 parameter: a pointer to the root of a binary tree. It must print the values in the tree's inorder traversal as a single line of space-separated values. Input Format Our hidden tester code passes the root node of a binary tree to your $inOrder* func
View Solution →Tree: Height of a Binary Tree
The height of a binary tree is the number of edges between the tree's root and its furthest leaf. For example, the following binary tree is of height : image Function Description Complete the getHeight or height function in the editor. It must return the height of a binary tree as an integer. getHeight or height has the following parameter(s): root: a reference to the root of a binary
View Solution →