Problem:
RSQ and RUQ

Write a program which manipulates a sequence $A$ = {$a_0, a_1, ..., a_{n-1}$} with the following operations:

$update(s, t, x)$: change $a_s, a_{s+1}, ..., a_t$ to $x$.

$getSum(s, t)$: print the sum of $a_s, a_{s+1}, ..., a_t$.

Note that the initial values of $a_i ( i = 0, 1, ..., n-1 )$ are 0.

Input

$n$ $q$
$query_1$
$query_2$
:
$query_q$

In the first line, $n$ (the number of elements in $A$) and $q$ (the number of queries) are given. Then, $i$-th query $query_i$ is given in the following format:

0 $s$ $t$ $x$

or

1 $s$ $t$

The first digit represents the type of the query. '0' denotes $update(s, t, x)$
and '1' denotes $find(s, t)$.

Output

For each $getSum$ query, print the sum in a line.

Constraints

$1 ≤ n ≤ 100000$

$1 ≤ q ≤ 100000$

$0 ≤ s ≤ t < n$

$-1000 ≤ x ≤ 1000$

Sample Input 1

6 7
0 1 3 1
0 2 4 -2
1 0 5
1 0 1
0 3 5 3
1 3 4
1 0 5

Sample Output 1

-5
1
6
8

Solution in C (judge verdict: Accepted)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h> // uint64_t

#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) > (b) ? (b) : (a))

int get_int(void) {
  int num;
  scanf("%d", &num);
  return num;
}

int get_int2(int *a1, int *a2) {
  scanf("%d %d", a1, a2);
  return 0;
}

int get_int3(int *a1, int *a2, int *a3) {
  scanf("%d %d %d", a1, a2, a3);
  return 0;
}

enum type {
    COMMAND_UPDATE,
    COMMAND_GET_SUM
};

struct range {
    int start;
    int end;
};

struct pair {
    int64_t lazy;
    int64_t val;
};

#define NUM_MAX 100000
#define NUM2_MAX (1<<17)
#define QUERY_MAX 100000

int is_overlap(struct range r1, struct range r2) {
    return r1.end > r2.start && r2.end > r1.start;
}

int is_contain(struct range this, struct range box) {
    return box.start <= this.start && this.end <= box.end;
}

#define INIT_VAL (2e+9)

void unlazy(struct pair *seg, int node, struct range nr) {
    int64_t lazy = seg[node].lazy;
    if(lazy == INIT_VAL) return;
    seg[node].val = lazy; //update
    seg[node].lazy = INIT_VAL;
    if(nr.end - nr.start > 1) {
        seg[node*2].lazy = lazy/2;
        seg[node*2+1].lazy = lazy/2;
    }
    return;
}


void update_range(struct pair *seg, int x, struct range r, int node, struct range nr) {
    unlazy(seg, node, nr);
    if(!is_overlap(r, nr)) return;
    if(is_contain(nr, r)) {
        seg[node].lazy = x * (nr.end - nr.start);
        unlazy(seg, node, nr);
        return;
    }
    struct range left = { nr.start, (nr.start + nr.end)/2 };
    struct range right = { (nr.start + nr.end)/2, nr.end };
    update_range(seg, x, r, node*2, left);
    update_range(seg, x, r, node*2+1, right);
    seg[node].val = seg[node*2].val + seg[node*2+1].val;
}

int64_t get_sum(struct pair *seg, struct range r, int node, struct range nr) {
    unlazy(seg, node, nr);
    if(!is_overlap(r, nr)) return 0;
    if(is_contain(nr, r)) {
        return seg[node].val;
    }
    struct range left = { nr.start, (nr.start + nr.end)/2 };
    struct range right = { (nr.start + nr.end)/2, nr.end };
    int64_t ans = 0;
    ans += get_sum(seg, r, node*2, left);
    ans += get_sum(seg, r, node*2+1, right);
    return ans;
}


#define ROOT_NODE 1
int main(void) {
    int num, queries;
    get_int2(&num, &queries);
    int num2 = 1;
    static int64_t ans[QUERY_MAX];
    int aidx = 0;
    while(num > num2) num2 *= 2;
    static struct pair seg[NUM2_MAX*2];
    int i;
    for(i = ROOT_NODE; i < num2*2; i++) seg[i].lazy = INIT_VAL;

    struct range whole = {0, num2};
    for(i = 0; i < queries; i++) {
        int start, end;
        int type;
        get_int3(&type, &start, &end);
        struct range r = {start, end+1};
        switch(type) {
            case COMMAND_UPDATE:
                {
                    int x = get_int();
                    update_range(seg, x, r, ROOT_NODE, whole);
                }
                break;
            case COMMAND_GET_SUM:
                ans[aidx++] = get_sum(seg, r, ROOT_NODE, whole);
                break;
            default:
                break;
        }
    }

    for(i = 0; i < aidx; i++) {
        printf("%lld\n", ans[i]);
    }
    return 0;
}