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

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 →

Tree : Top View

Given a pointer to the root of a binary tree, print the top view of the binary tree. The tree as seen from the top the nodes, is called the top view of the tree. For example : 1 \ 2 \ 5 / \ 3 6 \ 4 Top View : 1 -> 2 -> 5 -> 6 Complete the function topView and print the resulting values on a single line separated by space.

View Solution →

Tree: Level Order Traversal

Given a pointer to the root of a binary tree, you need to print the level order traversal of this tree. In level-order traversal, nodes are visited level by level from left to right. Complete the function levelOrder and print the values in a single line separated by a space. For example: 1 \ 2 \ 5 / \ 3 6 \ 4 F

View Solution →

Binary Search Tree : Insertion

You are given a pointer to the root of a binary search tree and values to be inserted into the tree. Insert the values into their appropriate position in the binary search tree and return the root of the updated binary tree. You just have to complete the function. Input Format You are given a function, Node * insert (Node * root ,int data) { } Constraints No. of nodes in the tree <

View Solution →