# HackerRank Swaps and Sum problem solution

In this HackerRank Swaps and Sum problem solution, you are given a sequence and we need to swap the first two elements of segment and second two-element and soon. also we have given two integers we need to find the sum between the range.

## Problem solution in 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);
out.close();
}

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

this.in = in;
}

public Input(String s) {
}

public String next() throws IOException {
sb.setLength(0);
while (true) {
if (c == -1) {
return null;
}
if (" \n\r\t".indexOf(c) == -1) {
sb.append((char)c);
break;
}
}
while (true) {
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());
}
}
}```

## Problem solution in 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;
}```

## Problem solution in 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;
}```