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

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 →