Algorithm


Problem Name: Data Structures - Swaps and Sum

Problem Link: https://www.hackerrank.com/challenges/swaps-and-sum/problem?isFullScreen=true

In this HackerRank in Data Structures - Swaps and Sum solutions,

You are given a sequence a1,a2, .... , an The task is to perform the following queries on it:

Type 1. Given two integers (1 <=  l < r <= n; r - l + 1 is even). Reorder the

a1,a2, .... , an -> a1,a2, .... , a(l-2), a(l-1) , [a(l+1), al , a(l+3),a(l+2), .... , ar, a(r-1)], a(r+1),a(r+2), .... , an

Input Format

The first line contains two integers n and q. The second line contains n integers a1,a2, .... , an,denoting initial sequence.

Each of the next q lines contains three integers tpi , li , ri where tpi enotes the type of the query, and li,ri are parameters of the query. It's guaranteed that for a first-type query (r - l + 1)

Constraints

2 <= n <= 2 * 10**5

1 <= q <= 2 * 10**5

1 <= ai <= 10**6

1 <= tpi <= 10**2

1 <= li <= ri <= n

Output Format

For each query of the second type print the required sum.

Sample Input

6 4
1 2 3 4 5 6
1 2 5
2 2 3
2 3 4
2 4 5

Example Output

5
7
9

Explanation

After the first query the sequence becomes [1, 3, 2, 5, 4, 6].

 

 

 

Code Examples

#1 Code Example with C Programming

Code - C Programming


#include <stdio.h>
#include <stdlib.h>
typedef struct _ct_node{
  int size;
  int priority;
  int value;
  long long sum;
  struct _ct_node *left,*right;
} ct_node;
long long get_sum(int x,int y,ct_node *root);
void get_size(ct_node *root);
ct_node* merge(ct_node *L,ct_node *R);
int sizeOf(ct_node *root);
long long sumOf(ct_node *root);
void recalc(ct_node *root);
void split(int x,ct_node **L,ct_node **R,ct_node *root);
void reverse(int x,int y);
void computeTree(int x);
int N,P[200000],T[200000],st[200000];
ct_node poll[200000],*odd,*even;

int main(){
  int Q,x,y,i;
  scanf("%d%d",&N,&Q);
  for(i = 0; i  <  N; i++){
    scanf("%d",&poll[i].value);
    poll[i].priority = P[i] = rand();
    poll[i].size=-1;
    poll[i].left = poll[i].right = NULL;
  }
  computeTree(0);
  computeTree(1);
  for(i = 0; i  <  N; i++)
    if(T[i] ==-1)
      if(i%2)
        odd = &poll[i];
      else
        even = &poll[i];
    else
      if(i < T[i])
        poll[T[i]].left = &poll[i];
      else
        poll[T[i]].right = &poll[i];
  get_size(odd);
  get_size(even);
  while(Q--){
    scanf("%d",&x);
    switch(x){
      case 1:
        scanf("%d%d",&x,&y);
        reverse(x,y);
        break;
      default:
        scanf("%d%d",&x,&y);
        if(x == y)
          if(x%2)
            printf("%lld\n",get_sum((x-1)/2,(x-1)/2,even));
          else
            printf("%lld\n",get_sum((x-1)/2,(x-1)/2,odd));
        else
          printf("%lld\n",get_sum((x-1)/2,(y-2)/2,odd)+get_sum(x/2,(y-1)/2,even));
    }
  }
  return 0;
}
long long get_sum(int x,int y,ct_node *root>{
  if(!root || x>y || x>root->size-1 || y<0>
    return 0;
  if(x  < = 0 && y >= root -> size-1)
    return root -> sum;
  int curidx = sizeOf(root -> left),t;
  long long ls,rs,ans = 0;
  if(curidx >= x && curidx <= y>
    ans = root -> value;
  if(y < curidx>
    ls = get_sum(x,y,root -> left);
  else
    ls = get_sum(x,curidx-1,root -> left);
  if(x > curidx)
    rs = get_sum(x-curidx-1,y-curidx-1,root->right);
  else
    rs = get_sum(0,y-curidx-1,root->right);
  return ans+ls+rs;
}
void get_size(ct_node *root){
  if(!root)
    return;
  int ls = 0,rs = 0;
  long long lsu = 0,rsu = 0;
  if(root->left){
    if(root -> left -> size == -1)
      get_size(root -> left);
    ls = root -> left -> size;
    lsu = root -> left -> sum;
  }
  if(root -> right){
    if(root -> right -> size == -1)
      get_size(root -> right);
    rs = root -> right -> size;
    rsu = root -> right -> sum;
  }
  root -> size = ls+rs+1;
  root -> sum = lsu+rsu+root -> value;
  return;
}
ct_node* merge(ct_node *L,ct_node *R){
  if(!L)
    return R;
  if(!R)
    return L;
  if(L->priority>R->priority){
    L->right=merge(L->right,R);
    recalc(L);
    return L;
  }
  R->left=merge(L,R->left);
  recalc(R);
  return R;
}
int sizeOf(ct_node *root){
  return (root)?root->size:0;
}
long long sumOf(ct_node *root){
  return (root)?root->sum:0;
}
void recalc(ct_node *root){
  root->size=sizeOf(root->left)+sizeOf(root->right)+1;
  root->sum=sumOf(root->left)+sumOf(root->right)+root->value;
  return;
}
void split(int x,ct_node **L,ct_node **R,ct_node *root){
  if(!root){
    *L=*R=NULL;
    return;
  }
  int curIndex=sizeOf(root->left);
  ct_node *t;
  if(curIndex<=x>{
    split(x-curIndex-1,&t,R,root->right);
    root->right=t;
    recalc(root);
    *L=root;
  }
  else{
    split(x,L,&t,root->left);
    root->left=t;
    recalc(root);
    *R=root;
  }
  return;
}
void reverse(int x,int y){
  ct_node *ol,*om,*or,*el,*em,*er;
  int A,B;
  A=(x-1)/2;
  B=(y-2)/2;
  split(A-1,&ol,&or,odd);
  split(B-A,&om,&or,or);
  A=x/2;
  B=(y-1)/2;
  split(A-1,&el,&er,even);
  split(B-A,&em,&er,er);
  odd=merge(merge(ol,em),or);
  even=merge(merge(el,om),er);
  return;
}
void computeTree(int x){
  int i,k,top=-1;
  for(i = x; i  <  N; i+=2){
    k=top;
    while(k >= 0 && P[st[k]]  <  P[i])
      k--;
    if(k != -1)
      T[i] = st[k];
    if(k < top>
      T[st[k+1]] = i;
    st[++k] = i;
    top = k;
  }
  T[st[0]] = -1;
  return;
}
Copy The Code & Try With Live Editor

#2 Code Example with C++ Programming

Code - C++ Programming


#include <algorithm>
#include <iostream>
#include <cstring>
#include <cassert>
#include <chrono>
#include <map>
#include <set>
#include <vector>
#include <complex>
#include <queue>
#include <tuple>
 
using namespace std;
typedef long long ll;

struct Tree {
    using D = ll;
    struct Node;
    using NP = Node*;
    static Node last_d;
    static NP last;
    struct Node {
        NP p, l, r;
        int sz;
        D v, sm;
        Node(D v) :p(nullptr), l(last), r(last), sz(1), v(v), sm(v) {}
        Node() : l(nullptr), r(nullptr), sz(0), v(0), sm(0) {}
        inline int pos() {
            if (p) {
                if (p->l == this) return -1;
                if (p->r == this) return 1;
            }
            return 0;
        }
        void rot() {
            NP qq = p->p;
            int pps = p->pos();
            if (p->l == this) {
                p->l = r; r->p = p;
                r = p; p->p = this;
            } else {
                p->r = l; l->p = p;
                l = p; p->p = this;
            }
            p->update(); update();
            p = qq;
            if (!pps) return;
            if (pps == -1) {
                qq->l = this;
            } else {
                qq->r = this;
            }
            qq->update();
        }
        void splay() {
            assert(this != last);
            supush();
            int ps;
            while ((ps = pos())) {
                int pps = p->pos();
                if (!pps) {
                    rot();
                } else if (ps == pps) {
                    p->rot(); rot();
                } else {
                    rot(); rot();
                }
            }
        }
        NP splay(int k) {
            assert(this != last);
            assert(0  < = k && k < sz);
            if (k < l->sz) {
                return l->splay(k);
            } else if (k == l->sz) {
                splay();
                return this;
            } else {
                return r->splay(k-(l->sz+1));
            }
        }
        void supush() {
            if (pos()) {
                p->supush();
            }
            push();
        }
        //pushpush""
        void push() { 
            assert(sz);
        }
        NP update() {
            assert(this != last);
            sz = 1+l->sz+r->sz;
            sm = v;
            if (l->sz) {
                sm += l->sm;
            }
            if (r->sz) {
                sm += r->sm;
            }
            return this;
        }
    } *n;
    static NP merge(NP l, NP r) {
        if (r == last) {
            return l;
        }
        r = r->splay(0);
        assert(r->l == last);
        r->l = l;
        l->p = r;
        return r->update();
    }
    static pair < NP, NP> split(NP x, int k) {
        assert(0 <= k && k <= x->sz);
        if (k == x->sz) {
            return {x, last};
        }
        x = x->splay(k);
        NP l = x->l;
        l->p = nullptr;
        x->l = last;
        return {l, x->update()};
    }
    static NP built(int sz, ll d[]) {
        if (!sz) return last;
        int md = sz/2;
        NP x = new Node(d[md]);
        x->l = built(md, d);
        x->l->p = x;
        x->r = built(sz-(md+1), d+(md+1));
        x->r->p = x;
        return x->update();
    }
    Tree() : n(last) {}
    Tree(NP n) : n(n) {}
    Tree(int sz, D d[]) {
        n = built(sz, d);
    }
    int sz() {
        return n->sz;
    }
    void insert(int k, D v) {
        auto u = split(n, k);
        n = merge(merge(u.first, new Node(v)), u.second);
    }
    void erase(int k) {
        auto u = split(n, k);
        n = merge(u.first, split(u.second, 1).second);
    }
    void merge(Tree t) {
        n = merge(n, t.n);
    }
    Tree split(int l) {
        auto a = split(n, l);
        n = a.first;
        return Tree(a.second);
    }
    D get(int l) {
        auto a = split(n, l);
        auto b = split(a.second, 1);
        D res = b.first->v;
        n = merge(merge(a.first, b.first), b.second);
        return res;
    }
    D sum(int l, int r) {
        auto b = split(n, r);
        auto a = split(b.first, l);
        D res = a.second->sm;
        n = merge(merge(a.first, a.second), b.second);
        return res;
    }
};
Tree::Node Tree::last_d = Tree::Node();
Tree::NP Tree::last = &last_d;

const int MN = 100100;
ll a[2][MN];
Tree tr[2];
int main() {
    int n, q;
    scanf("%d %d", &n, &q);
    for (int i = 0; i  <  n; i++) {
        scanf("%lld", &a[i%2][i/2]);
    }
    tr[0] = Tree((n+1)/2, a[0]);
    tr[1] = Tree(n/2, a[1]);
    for (int qc = 0; qc  <  q; qc++) {
        int t; ll l, r;
        scanf("%d %lld %lld", &t, &l, &r); l--;
        if (t == 1) {
            Tree x[2], y[2];
            x[1] = tr[0].split((r+1)/2);
            x[0] = tr[0].split((l+1)/2);
            y[1] = tr[1].split(r/2);
            y[0] = tr[1].split(l/2);
            tr[0].merge(y[0]);
            tr[0].merge(x[1]);
            tr[1].merge(x[0]);
            tr[1].merge(y[1]);
        } else {
            printf("%lld\n", tr[0].sum((l+1)/2, (r+1)/2) + tr[1].sum(l/2, r/2));
        }
    }
    return 0;
}
Copy The Code & Try With Live Editor

#3 Code Example with Java Programming

Code - Java Programming


import java.io.*;
import java.util.Random;

public class HR_swaps_and_sum {

    static int size(Node x) {
        return x == null ? 0 : x.size;
    }

    static long sum(Node x) {
        return x == null ? 0 : x.sum;
    }

    static class Node {
        final static Random rnd = new Random(42);

        Node l, r;
        int depth;
        int size;
        long val, sum;

        Node(long val) {
            depth = rnd.nextInt();
            this.val = val;
            rehash();
        }

        void rehash() {
            size = 1;
            sum = val;
            if (l != null) {
                size += l.size;
                sum += l.sum;
            }
            if (r != null) {
                size += r.size;
                sum += r.sum;
            }
        }
    }

    static Node[] split(Node x, int left) {
        if (x == null) {
            return new Node[2];
        }
        Node[] p;
        if (left  < = size(x.l)) {
            p = split(x.l, left);
            x.l = p[1];
            p[1] = x;
        } else {
            p = split(x.r, left - size(x.l) - 1);
            x.r = p[0];
            p[0] = x;
        }
        x.rehash();
        return p;
    }

    static Node[] splitAt(Node x, int... at) {
        Node[] ret = new Node[at.length + 1];
        for (int i = at.length - 1; i >= 0; --i) {
            Node[] tmp = split(x, at[i]);
            ret[i + 1] = tmp[1];
            x = tmp[0];
        }
        ret[0] = x;
        return ret;
    }

    static Node merge(Node l, Node r) {
        if (l == null) {
            return r;
        }
        if (r == null) {
            return l;
        }
        if (l.depth > r.depth) {
            r.l = merge(l, r.l);
            r.rehash();
            return r;
        } else {
            l.r = merge(l.r, r);
            l.rehash();
            return l;
        }
    }

    static Node mergeAll(Node... nodes) {
        Node ret = null;
        for (Node node : nodes) {
            ret = merge(ret, node);
        }
        return ret;
    }

    public static void solve(Input in, PrintWriter out) throws IOException {
        int n = in.nextInt();
        int q = in.nextInt();
        Node even = null, odd = null;
        for (int i = 0; i  <  n; ++i) {
            if (i % 2 == 0) {
                even = merge(even, new Node(in.nextLong()));
            } else {
                odd = merge(odd, new Node(in.nextLong()));
            }
        }
        for (int it = 0; it  <  q; ++it) {
            int type = in.nextInt();
            int l = in.nextInt() - 1;
            int r = in.nextInt();
            Node[] splitEven = splitAt(even, (l + 1) / 2, (r + 1) / 2);
            Node[] splitOdd = splitAt(odd, l / 2, r / 2);
            if (type == 1) {
                if (splitEven[1].size != (r - l) / 2 || splitOdd[1].size != (r - l) / 2) {
                    throw new AssertionError();
                }
                even = mergeAll(splitEven[0], splitOdd[1], splitEven[2]);
                odd = mergeAll(splitOdd[0], splitEven[1], splitOdd[2]);
            } else {
                out.println(sum(splitEven[1]) + sum(splitOdd[1]));
                even = mergeAll(splitEven);
                odd = mergeAll(splitOdd);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
        solve(new Input(new BufferedReader(new InputStreamReader(System.in))), out);
        out.close();
    }

    static class Input {
        BufferedReader in;
        StringBuilder sb = new StringBuilder();

        public Input(BufferedReader in) {
            this.in = in;
        }

        public Input(String s) {
            this.in = new BufferedReader(new StringReader(s));
        }

        public String next() throws IOException {
            sb.setLength(0);
            while (true) {
                int c = in.read();
                if (c == -1) {
                    return null;
                }
                if (" \n\r\t".indexOf(c) == -1) {
                    sb.append((char)c);
                    break;
                }
            }
            while (true) {
                int c = in.read();
                if (c == -1 || " \n\r\t".indexOf(c) != -1) {
                    break;
                }
                sb.append((char)c);
            }
            return sb.toString();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
    }
}
Copy The Code & Try With Live Editor
Advertisements

Demonstration


Previous
[Solved] Recalling Early Days GP with Trees solution in Hackerrank - Hacerrank solution C, C++, java,js, Python
Next
[Solved] Arithmetic Progressions solution in Hackerrank - Hacerrank solution C, C++, java,js, Python