Color Inversion on a Huge Chessboard
Source: aizu

Color Inversion on a Huge Chessboard

You are given a set of square cells arranged in a chessboard-like pattern with n horizontal rows and n vertical columns. Rows are numbered 1 through n from top to bottom, and columns are also numbered 1 through n from left to right.

Initially, the cells are colored as in a chessboard, that is, the cell in the row $i$ and the column $j$ is colored black if $i + j$ is odd and is colored white if it is even.

Color-inversion operations, each of which is one of the following two, are made one after another.

Invert colors of a row: Given a row number, invert colors of all the cells in the specified row. The white cells in the row become black and the black ones become white.

Invert colors of a column: Given a column number, invert colors of all the cells in the specified column. The white cells in the column become black and the black ones become white.

The number of distinct areas after each of the operations should be counted. Here, an area means a group of directly or indirectly connected cells of the same color. Two cells are said to be directly connected when they share an edge.

Input

The input consists of a single test case of the following format.

$n$ $q$
$operation_1$
.
.
.
$operation_q$


The integer $n$ is the number of rows and columns ($1 \leq n \leq 5 \times 10^5$). The integer $q$ is the number of operations ($1 \leq q \leq 5 \times 10^5$). The following $q$ lines represent operations to be made in this order. Each of them is given in either of the following forms.

ROW $i$: the operation “invert colors of a row” applied to the row $i$ ($1 \leq i \leq n$).
COLUMN $j$: the operation “invert colors of a column” applied to the column $j$ ($1 \leq j \leq n$).
Output

Output $q$ lines. The $k$-th line should contain an integer denoting the number of areas after the $k$-th operation is made.

Sample Input 1
3 3
ROW 2
COLUMN 3
ROW 2

Sample Output 1
3
2
6

Sample Input 2
200000 2
ROW 1
ROW 1

Sample Output 2
39999800000
40000000000



Figure F.1. Illustration of Sample Input 1

C++ solution:
#include <bits/stdc++.h>

// NOLINTBEGIN
// clang-format off
// DO NOT REMOVE THIS MESSAGE. The mess that follows is a minified build of
// https://github.com/purplesyringa/blazingio. Refer to the repository for
// a human-readable version and documentation.
// Options: cbfoiedrhWLMXaIaAn
#define M$(x,...)_mm256_##x##_epi8(__VA_ARGS__)
#define $u(...)__VA_ARGS__
#if __APPLE__
#define $m(A,B)A
#else
#define $m(A,B)B
#endif
#if _WIN32
#define $w(A,B)A
#else
#define $w(A,B)B
#endif
#if __i386__|_M_IX86
#define $H(A,B)A
#else
#define $H(A,B)B
#endif
#if __aarch64__
#define $a(A,B)A
#else
#define $a(A,B)B
#endif
#define $P(x)void F(x K){
#define $T template<$c T
#define $c class
#define $C constexpr
#define $R return
#define $O operator
#define $r $R*this;
#include<array>
#include<bitset>
#include<complex>
#include<cstring>
#include $a(<arm_neon.h>,<immintrin.h>)
#include<stdint.h>
#include $w(<windows.h>,<sys/mman.h>)
#include<sys/stat.h>
#include $w(<io.h>,<unistd.h>)
#include $w(<ios>,<sys/resource.h>)
#ifdef _MSC_VER
#define __builtin_add_overflow(a,b,c)_addcarry_u64(0,a,b,c)
#define $s
#else
$H(,uint64_t _umul128(uint64_t a,uint64_t b,uint64_t*D){auto x=(__uint128_t)a*b;*D=x>>64;$R x;})
#define $s $a(,__attribute__((target("avx2"))))
#endif
#define $z $a(16,32)
#define $t $a(uint8x16_t,__m256i)
#define $I $w(__forceinline,__attribute__((always_inline)))
#define $F M(),
#define E$(x)if(!(x))abort();
$w(LONG WINAPI $x(_EXCEPTION_POINTERS*);,)namespace $f{using namespace std;struct B{enum $c A:char{}c;B&$O=(char x){c=A{x};$r}$O char(){$R(char)c;}};$C uint64_t C=~0ULL/255;struct D{string&K;};static B E[65568];template<int F>struct G{B*H,*S;void K(off_t C){$w(char*D=(char*)VirtualAlloc(0,(C+8191)&-4096,8192,1);E$(D)E$(VirtualFree(D,0,32768))DWORD A=C&-65536;E$(!A||MapViewOfFileEx(CreateFileMapping(GetStdHandle(-10),0,2,0,A,0),4,0,0,0,D)==D)E$(VirtualAlloc(D+A,65536,12288,4)==D+A)E$(~_lseek(0,A,0))DWORD E=0;ReadFile(GetStdHandle(-10),D+A,65536,&E,0);,int A=getpagesize();char*D=(char*)mmap(0,C+A,3,2,0,0);E$(D!=(void*)-1)E$(mmap(D+((C+A-1)&-A),A,3,$m(4114,50),-1,0)!=(void*)-1))H=(B*)D+C;*H=10;H[1]=48;H[2]=0;S=(B*)D;}void L(){H=S=E;}$I void M(){if(F&&S==H){$w(DWORD A=0;ReadFile(GetStdHandle(-10),S=E,65536,&A,0);,$a($u(register long A asm("x0")=0,D asm("x1")=(long)E,G asm("x2")=65536,C asm($m("x16","x8"))=$m(3,63);asm volatile("svc 0" $m("x80",):"+r"(A),"+r"(D):"r"(C),"r"(G));S=launder(E);),off_t A=$H(3,$m(33554435,0));B*D=E;asm volatile($H("int $128","syscall"):"+a"(A),$H("+c"(D):"b","+S"(D):"D")(0),"d"(65536)$H(,$u(:"rcx","r11")));S=D;))H=S+A;*H=10;if(!A)E[1]=48,E[2]=0;}}$T>$I void N(T&x){while($F(*S&240)==48)x=x*10+(*S++-48);}$T>$I decltype((void)~T{1})O(T&x){M();int A=is_signed_v<T>&&*S==45;S+=A;N(x=0);x=A?1+~x:x;}$T>$I decltype((void)T{1.})O(T&x){M();int A=*S==45;S+=A;$F S+=*S==43;uint64_t n=0;int i=0;for(;i<18&&($F*S&240)==48;i++)n=n*10+*S++-48;int B=20;int C=*S==46;S+=C;for(;i<18&&($F*S&240)==48;i++)n=n*10+*S++-48,B-=C;x=(T)n;while(($F*S&240)==48)x=x*10+*S++-48,B-=C;if(*S==46)S++,C=1;while(($F*S&240)==48)x=x*10+*S++-48,B-=C;int D;if((*S|32)==101)S++,$F S+=*S==43,O(D),B+=D;static $C auto E=[](){array<T,41>E{};T x=1;for(int i=21;i--;)E[40-i]=x,E[i]=1/x,x*=10;$R E;}();while(B>40)x*=(T)1e10,B-=10;while(B<0)x*=(T)1e-10,B+=10;x*=E[B];x=A?-x:x;}$I void O(bool&x){$F x=*S++==49;}$I void O(char&x){$F x=*S++;}$I void O(uint8_t&x){$F x=*S++;}$I void O(int8_t&x){$F x=*S++;}$T>$s void P(string&K,T C){M();B*G=S;C();K.assign((char*)G,S-G);while(F&&S==H&&($F H!=E)){C();K.append(E,S);}}$s void O(string&K){P(K,[&]()$s{B*p=S;$w(ULONG R;,)$t x;$a(uint64x2_t A;while(memcpy(&x,p,16),A=(uint64x2_t)(x<33),!(A[0]|A[1]))p+=16;S=p+(A[0]?0:8)+$w((_BitScanForward64(&R,A[0]?:A[1]),R),__builtin_ctzll(A[0]?:A[1]))/8;,int J;$t C=M$(set1,32);while(memcpy(&x,p,32),!(J=M$(movemask,M$(cmpeq,C,_mm256_max_epu8(C,x)))))p+=32;S=p+$w((_BitScanForward(&R,J),R),__builtin_ctz(J));)});}$s void O(D&A){P(A.K,[&](){S=(B*)memchr(S,10,H-S+1);});if(A.K.size()&&A.K.back()==13)A.K.pop_back();if(A.K.empty()||S<H)S+=*S==10;}$T>$I void O(complex<T>&K){T A,B{};if($F*S==40){S++;O(A);if($F*S++==44)Q(B),S++;}else O(A);K={A,B};}template<size_t N>$s void O(bitset<N>&K){if(N>4095&&!*this)$R;ptrdiff_t i=N;while(i)if($F i%$z||H-S<$z)K[--i]=*S++==49;else{B*p=S;for(int64_t j=0;j<min(i,H-S)/$z;j++){i-=$z;$t x;memcpy(&x,p,$z);$a(auto B=(uint8x16_t)vdupq_n_u64(~2ULL/254)&(48-x);auto C=vzip_u8(vget_high_u8(B),vget_low_u8(B));uint16_t y=vaddvq_u16((uint16x8_t)vcombine_u8(C.val[0],C.val[1]));,uint64_t a=~0ULL/65025;uint32_t y=$w(_byteswap_ulong,__builtin_bswap32)(M$(movemask,M$(shuffle,_mm256_slli_epi32(x,7),_mm256_set_epi64x(a+C*24,a+C*16,a+C*8,a))));)p+=$z;memcpy((char*)&K+i/8,&y,$z/8);}S=p;}}$T>$I void Q(T&K){if(!is_same_v<T,D>)while($F 0<=*S&&*S<33)S++;O(K);}$O bool(){$R!!*this;}bool $O!(){$R S>H;}};struct $i{G<0>A;G<1>B;$i(){struct stat D;E$(~fstat(0,&D))(D.st_mode>>12)==8?A.K(D.st_size):B.L();}$i*tie(nullptr_t){$R this;}void sync_with_stdio(bool){}$T>$I $i&$O>>(T&K){A.S?A.Q(K):B.Q(K);$r}$O bool(){$R!!*this;}bool $O!(){$R A.S?!A:!B;}};uint16_t A[100];char L[64]{1};struct
$o{char*D;B*S;int J;$o(){$w(E$(D=(char*)VirtualAlloc(0,536870912,8192,4))E$(VirtualAlloc(D,4096,4096,260))AddVectoredExceptionHandler(1,$x);,size_t C=536870912;$m(,struct rlimit E;getrlimit(RLIMIT_AS,&E);if(~E.rlim_cur)C=25165824;)D=(char*)mmap(0,C,3,$m(4162,16418),-1,0);E$(D!=(void*)-1))S=(B*)D;for(int i=0;i<100;i++)A[i]=(48+i/10)|((48+i%10)<<8);for(int i=1;i<64;i++)L[i]=L[i-1]+(0x8922489224892249>>i&1);}~$o(){flush(!J);}void flush(int F=0){$w(J=1;auto E=GetStdHandle(-11);auto C=F?ReOpenFile(E,1073741824,7,2684354560):(void*)-1;DWORD A;E$(C==(void*)-1?WriteFile(E,D,DWORD((char*)S-D),&A,0):(WriteFile(C,D,DWORD(((char*)S-D+4095)&-4096),&A,0)&&~_chsize(1,int((char*)S-D)))),auto G=D;ssize_t A;while((A=write(1,G,(char*)S-G))>0)G+=A;E$(~A))S=(B*)D;}$P(char)*S++=K;}$P(uint8_t)*S++=K;}$P(int8_t)*S++=K;}$P(bool)*S++=48+K;}$T>decltype((void)~T{1})F(T K){using D=make_unsigned_t<T>;D C=K;if(K<0)F('-'),C=1+~C;static $C auto N=[](){array<D,5*sizeof(T)/2>N{};D n=1;for(size_t i=1;i<N.size();i++)n*=10,N[i]=n;$R N;}();$w(ULONG M;,)int G=L[$w(($H(_BitScanReverse(&M,ULONG((int64_t)C>>32))?M+=32:_BitScanReverse(&M,(ULONG)C|1),_BitScanReverse64(&M,C|1)),M),63^__builtin_clzll(C|1))];G-=C<N[G-1];uint16_t H[20];if $C(sizeof(T)==2){auto n=33555U*C-C/2;uint64_t H=A[n>>25];n=(n&33554431)*25;H|=A[n>>23]<<16;H|=uint64_t(48+((n&8388607)*5>>22))<<32;H>>=40-G*8;memcpy(S,&H,8);}else if $C(sizeof(T)==4){auto n=1441151881ULL*C;$H(n>>=25;n++;for(int i=0;i<5;i++){H[i]=A[n>>32];n=(n&~0U)*100;},int K=57;auto J=~0ULL>>7;for(int i=0;i<5;i++){H[i]=A[n>>K];n=(n&J)*25;K-=2;J/=4;})memcpy(S,(B*)H+10-G,16);}else{$H($u(if(C<(1ULL<<32)){$R F((uint32_t)C);}auto J=(uint64_t)1e10;auto x=C/J,y=C%J;int K=100000,b[]{int(x/K),int(x%K),int(y/K),int(y%K)};B H[40];for(int i=0;i<4;i++){uint32_t n=(429497ULL*b[i]>>7)+1;B*p=H+i*5;*p=48+(n>>25);n=(n&~0U>>7)*25;memcpy(p+1,A+(n>>23),2);memcpy(p+3,A+((n&~0U>>9)*25>>21),2);}),$u(uint64_t D,E=_umul128(18,C,&D),F;_umul128(0x725dd1d243aba0e8,C,&F);D+=__builtin_add_overflow(E,F+1,&E);for(int i=0;i<10;i++)H[i]=A[D],E=_umul128(100,E,&D);))memcpy(S,(B*)H+20-G,20);}S+=G;}$T>decltype((void)T{1.})F(T K){if(K<0)F('-'),K=-K;auto G=[&](){auto x=uint64_t(K*1e12);$H($u(x-=x>999999999999;uint32_t n[]{uint32_t(x/1000000*429497>>7)+1,uint32_t(x%1000000*429497>>7)+1};int K=25,J=~0U>>7;for(int i=0;i<3;i++){for(int j=0;j<2;j++)memcpy(S+i*2+j*6,A+(n[j]>>K),2),n[j]=(n[j]&J)*25;K-=2;J/=4;}S+=12;),$u(uint64_t D,E=_umul128(472236648287,x,&D)>>8;E|=D<<56;D>>=8;E++;for(int i=0;i<6;i++)memcpy(S,A+D,2),S+=2,E=_umul128(100,E,&D);))};if(!K)$R F('0');if(K>=1e16){K*=(T)1e-16;int B=16;while(K>=1)K*=(T).1,B++;F("0.");G();F('e');F(B);}else if(K>=1){auto B=(uint64_t)K;F(B);if(K-=B)F('.'),G();}else F("0."),G();}$P(const char*)$w(size_t A=strlen(K);memcpy((char*)S,K,A);S+=A;,S=(B*)stpcpy((char*)S,K);)}$P(const uint8_t*)F((char*)K);}$P(const int8_t*)F((char*)K);}$P(string_view)memcpy(S,K.data(),K.size());S+=K.size();}$T>$P(complex<T>)*this<<'('<<K.real()<<','<<K.imag()<<')';}template<size_t N>$s $P(const bitset<N>&)auto i=N;while(i%$z)*S++=48+K[--i];B*p=S;while(i){i-=$z;$a(uint16_t,uint32_t)x;memcpy(&x,(char*)&K+i/8,$z/8);$a(auto A=(uint8x8_t)vdup_n_u16(x);vst1q_u8((uint8_t*)p,48-vtstq_u8(vcombine_u8(vuzp2_u8(A,A),vuzp1_u8(A,A)),(uint8x16_t)vdupq_n_u64(~2ULL/254)));,auto b=_mm256_set1_epi64x(~2ULL/254);_mm256_storeu_si256(($t*)p,M$(sub,M$(set1,48),M$(cmpeq,_mm256_and_si256(M$(shuffle,_mm256_set1_epi32(x),_mm256_set_epi64x(0,C,C*2,C*3)),b),b)));)p+=$z;}S=p;}$T>$o&$O<<(const T&K){F(K);$r}$o&$O<<($o&(*A)($o&)){$R A(*this);}};struct $e{$T>$e&$O<<(const T&K){$r}$e&$O<<($e&(*A)($e&)){$R A(*this);}};}namespace std{$f::$i i$;$f::$o o$;$f::$e e$;$f::$i&getline($f::$i&B,string&K){$f::D A{K};$R B>>A;}$f::$o&flush($f::$o&B){if(!i$.A.S)B.flush();$R B;}$f::$o&endl($f::$o&B){$R B<<'\n'<<flush;}$f::$e&endl($f::$e&B){$R B;}$f::$e&flush($f::$e&B){$R B;}}$w(LONG WINAPI $x(_EXCEPTION_POINTERS*A){auto C=A->ExceptionRecord;auto B=C->ExceptionInformation[1];if(C->ExceptionCode==2147483649&&B-(ULONG_PTR)std::o$.D<0x40000000){E$(VirtualAlloc((char*)B,16777216,4096,4)&&VirtualAlloc((char*)(B+16777216),4096,4096,260))$R-1;}$R 0;},)
#define freopen(...)if(freopen(__VA_ARGS__)==stdin)std::i$=$f::$i{}
#define cin i$
#define cout o$
#ifdef ONLINE_JUDGE
#define cerr e$
#define clog e$
#endif
// End of blazingio
// NOLINTEND
// clang-format on

using namespace std;

bool rows[500001], cols[500001];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    #ifdef BACKER
        freopen("input.txt", "r", stdin);
        // freopen("output.txt", "w", stdout);
    #endif

    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) rows[i] = cols[i] = i % 2;
    int cntc = n, cntr = n;
    while (q--) {
        string type;
        int i, tmp = 0;
        cin >> type >> i;
        if (type[0] == 'R') {
            rows[i] = !rows[i];
            if (i - 1 >= 1) {
                if (rows[i] == rows[i - 1]) tmp--;
                else tmp++;
            }
            if (i + 1 <= n) {
                if (rows[i] == rows[i + 1]) tmp--;
                else tmp++;
            }
            cntr += tmp;
        }
        else {
            cols[i] = !cols[i];
            if (i - 1 >= 1) {
                if (cols[i] == cols[i - 1]) tmp--;
                else tmp++;
            }
            if (i + 1 <= n) {
                if (cols[i] == cols[i + 1]) tmp--;
                else tmp++;
            }
            cntc += tmp;
        }
        cout << 1ll * cntr * cntc << "\n";
    }
    return 0;
}

Go solution:
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	scanner.Scan()
	n, _ := strconv.Atoi(scanner.Text())
	scanner.Scan()
	q, _ := strconv.Atoi(scanner.Text())

	rowInverted := make([]bool, n)
	colInverted := make([]bool, n)

	rows := n
	cols := n
	areas := int64(rows) * int64(cols)

	for i := 0; i < q; i++ {
		scanner.Scan()
		op := scanner.Text()
		scanner.Scan()
		xStr := scanner.Text()
		x, _ := strconv.Atoi(xStr)
		x--

		if op == "ROW" {
			rowInverted[x] = !rowInverted[x]
			if n == 1 {
				areas = 1
			} else {
				if x == 0 {
					if rowInverted[x] == rowInverted[x+1] {
						rows++
					} else {
						rows--
					}
				} else if x == n-1 {
					if rowInverted[x] == rowInverted[x-1] {
						rows++
					} else {
						rows--
					}
				} else {
					prev := rowInverted[x-1]
					next := rowInverted[x+1]
					current := rowInverted[x]
					if (prev == current) && (next == current) {
						rows += 2
					} else if (prev != current) && (next != current) {
						rows -= 2
					}
				}
				areas = int64(rows) * int64(cols)
			}
		} else if op == "COLUMN" {
			colInverted[x] = !colInverted[x]
			if n == 1 {
				areas = 1
			} else {
				if x == 0 {
					if colInverted[x] == colInverted[x+1] {
						cols++
					} else {
						cols--
					}
				} else if x == n-1 {
					if colInverted[x] == colInverted[x-1] {
						cols++
					} else {
						cols--
					}
				} else {
					prev := colInverted[x-1]
					next := colInverted[x+1]
					current := colInverted[x]
					if (prev == current) && (next == current) {
						cols += 2
					} else if (prev != current) && (next != current) {
						cols -= 2
					}
				}
				areas = int64(rows) * int64(cols)
			}
		}
		fmt.Println(areas)
	}
}

Java solution:
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int q = Integer.parseInt(st.nextToken());

        if (n == 1) {
            for (int i = 0; i < q; i++) {
                br.readLine();
                pw.println(1);
            }
            pw.close();
            return;
        }

        int[] rowInverted = new int[n];
        int[] colInverted = new int[n];
        long connectedRows = n;
        long connectedCols = n;
        long totalAreas = (long) n * n;

        for (int k = 0; k < q; k++) {
            st = new StringTokenizer(br.readLine());
            String operation = st.nextToken();
            int x = Integer.parseInt(st.nextToken()) - 1;

            if (operation.equals("ROW")) {
                rowInverted[x] ^= 1;
                if (x == 0) {
                    if (rowInverted[x] == rowInverted[x + 1]) {
                        connectedRows++;
                        totalAreas += connectedCols;
                    } else {
                        connectedRows--;
                        totalAreas -= connectedCols;
                    }
                } else if (x == n - 1) {
                    if (rowInverted[x] == rowInverted[x - 1]) {
                        connectedRows++;
                        totalAreas += connectedCols;
                    } else {
                        connectedRows--;
                        totalAreas -= connectedCols;
                    }
                } else {
                    boolean sameLeft = (rowInverted[x] == rowInverted[x - 1]);
                    boolean sameRight = (rowInverted[x] == rowInverted[x + 1]);
                    if (sameLeft && sameRight) {
                        connectedRows += 2;
                        totalAreas += 2 * connectedCols;
                    } else if (!sameLeft && !sameRight) {
                        connectedRows -= 2;
                        totalAreas -= 2 * connectedCols;
                    }
                }
            } else if (operation.equals("COLUMN")) {
                colInverted[x] ^= 1;
                if (x == 0) {
                    if (colInverted[x] == colInverted[x + 1]) {
                        connectedCols++;
                        totalAreas += connectedRows;
                    } else {
                        connectedCols--;
                        totalAreas -= connectedRows;
                    }
                } else if (x == n - 1) {
                    if (colInverted[x] == colInverted[x - 1]) {
                        connectedCols++;
                        totalAreas += connectedRows;
                    } else {
                        connectedCols--;
                        totalAreas -= connectedRows;
                    }
                } else {
                    boolean sameLeft = (colInverted[x] == colInverted[x - 1]);
                    boolean sameRight = (colInverted[x] == colInverted[x + 1]);
                    if (sameLeft && sameRight) {
                        connectedCols += 2;
                        totalAreas += 2 * connectedRows;
                    } else if (!sameLeft && !sameRight) {
                        connectedCols -= 2;
                        totalAreas -= 2 * connectedRows;
                    }
                }
            }
            pw.println(totalAreas);
        }
        pw.close();
    }
}

JavaScript solution:
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

function main() {
    let n, q;
    let lineCount = 0;
    let operations = [];
    
    rl.on('line', (line) => {
        if (lineCount === 0) {
            const parts = line.trim().split(/\s+/);
            n = parseInt(parts[0], 10);
            q = parseInt(parts[1], 10);
            lineCount++;
        } else {
            operations.push(line.trim());
            if (operations.length === q) {
                rl.close();
            }
        }
    }).on('close', () => {
        solve(n, q, operations);
    });
}

function solve(n, q, operations) {
    const rowInverted = new Array(n).fill(0);
    const colInverted = new Array(n).fill(0);
    let rows = n;
    let cols = n;
    let areas = BigInt(n) * BigInt(n);

    for (const op of operations) {
        const parts = op.split(/\s+/);
        const type = parts[0];
        const x = parseInt(parts[1], 10) - 1; // converting to 0-based index

        if (n === 1) {
            console.log(1);
            continue;
        }

        if (type === 'ROW') {
            rowInverted[x] ^= 1;
            if (x === 0) {
                if (rowInverted[x] === rowInverted[x + 1]) {
                    rows += 1;
                    areas += BigInt(cols);
                } else {
                    rows -= 1;
                    areas -= BigInt(cols);
                }
            } else if (x === n - 1) {
                if (rowInverted[x] === rowInverted[x - 1]) {
                    rows += 1;
                    areas += BigInt(cols);
                } else {
                    rows -= 1;
                    areas -= BigInt(cols);
                }
            } else {
                const prevSame = rowInverted[x] === rowInverted[x - 1];
                const nextSame = rowInverted[x] === rowInverted[x + 1];
                if (prevSame && nextSame) {
                    rows += 2;
                    areas += BigInt(cols) * 2n;
                } else if (!prevSame && !nextSame) {
                    rows -= 2;
                    areas -= BigInt(cols) * 2n;
                }
            }
        } else if (type === 'COLUMN') {
            colInverted[x] ^= 1;
            if (x === 0) {
                if (colInverted[x] === colInverted[x + 1]) {
                    cols += 1;
                    areas += BigInt(rows);
                } else {
                    cols -= 1;
                    areas -= BigInt(rows);
                }
            } else if (x === n - 1) {
                if (colInverted[x] === colInverted[x - 1]) {
                    cols += 1;
                    areas += BigInt(rows);
                } else {
                    cols -= 1;
                    areas -= BigInt(rows);
                }
            } else {
                const prevSame = colInverted[x] === colInverted[x - 1];
                const nextSame = colInverted[x] === colInverted[x + 1];
                if (prevSame && nextSame) {
                    cols += 2;
                    areas += BigInt(rows) * 2n;
                } else if (!prevSame && !nextSame) {
                    cols -= 2;
                    areas -= BigInt(rows) * 2n;
                }
            }
        }
        console.log(areas.toString());
    }
}

main();

Python solution:
import sys
from collections import deque, defaultdict
from itertools import (
    accumulate,  # 累積和
    product,  # bit全探索 product(range(2),repeat=n)
    permutations,  # permutations : 順列全探索
    combinations,  # 組み合わせ（重複無し）
    combinations_with_replacement,  # 組み合わせ（重複可）
)
import math
from bisect import bisect_left, bisect_right
from heapq import heapify, heappop, heappush
import string
import inspect

# 外部ライブラリ
# from sortedcontainers import SortedSet, SortedList, SortedDict
sys.setrecursionlimit(10**7)
alph_s = tuple(string.ascii_lowercase)
alph_l = tuple(string.ascii_uppercase)
around4 = ((-1, 0), (1, 0), (0, -1), (0, 1))  # 上下左右
around8 = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1))
inf = float("inf")
mod = 998244353
input = lambda: sys.stdin.readline().rstrip()
pritn = lambda *x: print(*x)
PY = lambda: print("Yes")
PN = lambda: print("No")
SI = lambda: input()
IS = lambda: input().split()
II = lambda: int(input())
MII = lambda: map(int, input().split())
LMII = lambda: list(map(int, input().split()))

ans = []
n, q = MII()
row = [0] * n
column = [0] * n
for i in range(n):
    if i % 2 == 0:
        row[i] = 1
        column[i] = 1
    else:
        row[i] = 0
        column[i] = 0
y_renketu = n
t_renketu = n
z_renketu = n * n
for _ in range(q):
    op = input().split()
    x = int(op[1]) - 1
    if op[0] == "ROW":
        if x - 1 >= 0:
            if row[x - 1] == row[x]:
                y_renketu += 1
                z_renketu += t_renketu
            else:
                y_renketu -= 1
                z_renketu -= t_renketu

        if x + 1 < n:
            if row[x + 1] == row[x]:
                y_renketu += 1
                z_renketu += t_renketu
            else:
                y_renketu -= 1
                z_renketu -= t_renketu
        row[x] ^= 1
    else:
        if x - 1 >= 0:
            if column[x - 1] == column[x]:
                t_renketu += 1
                z_renketu += y_renketu
            else:
                t_renketu -= 1
                z_renketu -= y_renketu

        if x + 1 < n:
            if column[x + 1] == column[x]:
                t_renketu += 1
                z_renketu += y_renketu
            else:
                t_renketu -= 1
                z_renketu -= y_renketu
        column[x] ^= 1
    ans.append(z_renketu)
    # print(row)
    # print(column)
    # tmp = [[-1] * n for _ in range(n)]
    # for i in range(n):
    #     for j in range(n):
    #         tmp[i][j] = row[i] ^ column[j]
    # for i in tmp:
    #     print(i)
# 行・列だけなら、左右見て、同じなら-n,異なるなら+n
for i in ans:
    print(i)

Ruby solution:
def main
  input = gets.chomp.split
  n = input[0].to_i
  q = input[1].to_i

  row_inverted = Array.new(n, false)
  col_inverted = Array.new(n, false)
  rows = n
  cols = n
  areas = n * n

  q.times do
    op, x = gets.chomp.split
    x = x.to_i - 1

    if n == 1
      puts 1
      next
    end

    if op == 'ROW'
      row_inverted[x] = !row_inverted[x]
      if x == 0
        if row_inverted[x] == row_inverted[x + 1]
          rows += 1
          areas += cols
        else
          rows -= 1
          areas -= cols
        end
      elsif x == n - 1
        if row_inverted[x] == row_inverted[x - 1]
          rows += 1
          areas += cols
        else
          rows -= 1
          areas -= cols
        end
      else
        prev = row_inverted[x - 1]
        curr = row_inverted[x]
        nex = row_inverted[x + 1]
        if curr == prev && curr == nex
          rows += 2
          areas += cols * 2
        elsif curr != prev && curr != nex
          rows -= 2
          areas -= cols * 2
        end
      end
    elsif op == 'COLUMN'
      col_inverted[x] = !col_inverted[x]
      if x == 0
        if col_inverted[x] == col_inverted[x + 1]
          cols += 1
          areas += rows
        else
          cols -= 1
          areas -= rows
        end
      elsif x == n - 1
        if col_inverted[x] == col_inverted[x - 1]
          cols += 1
          areas += rows
        else
          cols -= 1
          areas -= rows
        end
      else
        prev = col_inverted[x - 1]
        curr = col_inverted[x]
        nex = col_inverted[x + 1]
        if curr == prev && curr == nex
          cols += 2
          areas += rows * 2
        elsif curr != prev && curr != nex
          cols -= 2
          areas -= rows * 2
        end
      end
    end
    puts areas
  end
end

main