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 :



title-img


                            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 →