Problem:
縄張り(Territory)
あなたは南北方向にとても長く伸びたたくさんの道路と，東西方向にとても長く伸びたたくさんの道路が交わった形をした街に住んでいる．隣り合う2 つの南北方向の道路の間隔は 1 km である．また，隣り合う 2 つの東西方向の道路の間隔も 1 km である．
この街には市役所が 1 つある．市役所のある交差点を $(0,0)$ と表す．この街の交差点は 2 つの整数 $i, j$ を用いて交差点 $(i, j)$ と表される．すなわち，交差点 $(i, j)$ とは，交差点 $(0,0)$ から東に $i$ km ($i < 0$ のときは西に $-i$ km)，北に $j$ km ( $j < 0$ のときは南に $-j$ km) 進んだ位置の交差点を表す．
市役所ではジョイ君という名の 1 匹の犬を飼っている．ジョイ君は $K$ 日間の散歩の計画を立てた．散歩の計画は以下の通りである．
$K$ 日のうち最初の日の朝にはジョイ君は交差点 $(0,0)$ にいる．ジョイ君は交差点 $(0,0)$ に印を付ける．$(0,0)$ 以外にはジョイ君が印を付けた交差点はない．
$K$ 日のそれぞれの日の昼に散歩を行う．1 日の散歩は $N$ 回のステップからなる．各ステップでは交差点から隣の交差点へと移動し，移動先に印を付ける．ジョイ君がそれぞれの日の昼にどう移動するかは日によらず一定である．
昼の移動が終わった後は，現在いる交差点で次の日の朝まで寝る．
市役所では $K$ 日間の散歩によってできるジョイ君の縄張りについて話題になっている．4 つの交差点 $(a,b),(a + 1,b),(a + 1,b + 1),(a,b + 1)$ のいずれにもジョイ君が 1 回以上印を付けているとき，4 つの交差点で囲まれた区画はジョイ君の縄張りに属する．
あなたは，ジョイ君の散歩計画から，ジョイ君の縄張りに属する区画の個数を計算するプログラムを作成することとなった．
この街の道路はとても長く，また，南北方向にも東西方向にも十分たくさんの道路があるため，散歩の途中でジョイ君が道路の端や街の端に到達することはない．
課題
ジョイ君の散歩計画が与えられると，ジョイ君の縄張りに属する区画の個数を求めるプログラムを作成せよ．
入力
標準入力から以下の入力を読み込め．
1 行目には 2 個の整数 $N, K$ が空白を区切りとして書かれている．これはそれぞれの日の散歩が $N$ 回のステップからなり，散歩計画が $K$ 日間に渡ることを表している．
2 行目には長さ $N$ の文字列 $S$ が書かれている．文字列 $S$ のうち左から $p$ 文字目 $(1 \leq p \leq N)$ の文字 $C_p$ は E，N，W，S のいずれかである．これらの文字は以下のことを表す．
文字 $C_p$ が E であるならば，$p$ 番目のステップで東隣の交差点に移動することを表す．
文字 $C_p$ が N であるならば，$p$ 番目のステップで北隣の交差点に移動することを表す．
文字 $C_p$ が W であるならば，$p$ 番目のステップで西隣の交差点に移動することを表す．
文字 $C_p$ が S であるならば，$p$ 番目のステップで南隣の交差点に移動することを表す．
ここで，交差点$(i, j)$ に対して東隣，北隣，西隣，南隣の交差点はそれぞれ，交差点 $(i + 1, j)$，交差点$(i, j + 1)$，交差点$(i - 1, j)$，交差点$(i, j - 1)$ である．
出力
標準出力に，ジョイ君の縄張りに属する区画の個数を 1 行で出力せよ．
制限
すべての入力データは以下の条件を満たす．
$1 \leq N \leq 100 000$
$1 \leq K \leq 1 000 000 000$
入出力例
入力例1
12 1
EENWSEEESWWS
出力例1
3
この入力例では，散歩は 1 日間で行われる．1 日目にジョイ君は市役所から出発して下図のように移動する．黒丸はジョイ君が印を付けた交差点，白丸はジョイ君が印を付けていない交差点，二重丸は市役所のある交差点，数字は各ステップを表す．
ジョイ君の移動経路
入力例 1 において，下図の斜線部分で示された 3 個の区画がジョイ君の縄張りに属する．
入力例1 におけるジョイ君の縄張り
入力例2
12 2
EENWSEEESWWS
出力例2
7
入力例 2 では，散歩が 2 日間に渡り行われる．それぞれの日の移動経路は入力例 1 と同一である．散歩が完了したとき，下図の斜線部分で示された 7 個の区画がジョイ君の縄張りに属する．
入力例2 におけるジョイ君の縄張り
入力例3
7 1
ENNWNNE
出力例3
0
入力例 3 では，ジョイ君の縄張りに属する区画は存在しない．
入力例4
16 5
WSESSSWWWEEENNNW
出力例4
21
第15回 日本情報オリンピック本選 課題   2016 年 2 月 14 日

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> Pi;
typedef pair<Pi, Pi> PPi;
typedef pair<ll, Pi> Ti;
const ll LLINF = 1LL << 60;
const int INF = (1 << 30) - 1;

char ch[] = "NESW";
ll dy[] = {-1, 0, 1, 0};
ll dx[] = {0, 1, 0, -1};

ll llabs(ll n) { return (n < 0 ? -n : n); }

ll N, K;
string S;
Pi route[200005];
ll vecy = 0, vecx = 0;
vector<PPi> data;
ll ans = 0;
ll sum[4][200005];

int main() {
    cin >> N >> K >> S;
    for (int i = 0; i < N; i++) {
        int j = 0;
        while (S[i] != ch[j]) j++;
        vecy += dy[j], vecx += dx[j];
        route[i + 1] = Pi(vecy, vecx);
    }
    route[0] = Pi(INF, 2 * N);

    // ルートの正規化
    for (int i = 1; i <= N; i++) {
        if (vecy < 0) route[i].first = -route[i].first;
        if (vecx < 0) route[i].second = -route[i].second;
        if (vecx == 0) swap(route[i].first, route[i].second);
        route[i].first += INF, route[i].second += N * 2;
    }
    vecy = llabs(vecy);
    vecx = llabs(vecx);
    if (vecx == 0) vecx = vecy, vecy = 0;
    sort(route, route + N + 1);

    if (vecx == 0) {
        for (int i = 0; i <= N;) {
            ll y = route[i].first, x = route[i].second;
            Pi *a = route, *b = route + N + 1;
            if (binary_search(a, b, Pi(y + 1, x)) && binary_search(a, b, Pi(y, x + 1)) && binary_search(a, b, Pi(y + 1, x + 1))) 
                ans++;
            while (i <= N && route[i].first == y && route[i].second == x) 
                i++;
        }
        cout << ans << endl;
        return 0;
    }

    // データの準備
    for (int i = 0; i <= N; i++) {
        ll y = route[i].first, x = route[i].second;
        data.push_back(PPi(Pi(y - x / vecx * vecy, x % vecx), Pi(x / vecx, x / vecx + K)));
    }
    sort(data.begin(), data.end());
    data.erase(unique(data.begin(), data.end()), data.end());

    for (int i = 0; i < data.size();) {
        vector<ll> comp;
        vector<Ti> d;
        map<ll, ll> conv;
        
        ll now[4] = {};

        ll r, u, ru;
        ll iy = data[i].first.first, ix = data[i].first.second;
        ll plus = (ix + 1) / vecx;
        Pi pp[4] = {data[i].first, Pi(iy - plus * vecy, (ix + 1) % vecx), Pi(iy + 1, ix), Pi(iy + 1 - plus * vecy, (ix + 1) % vecx)};
        Pi nop = Pi(-LLINF, -LLINF);
        ll pos[4];
        pos[0] = i;
        for (int j = 1; j < 4; j++) pos[j] = lower_bound(data.begin(), data.end(), PPi(pp[j], nop)) - data.begin();
        for (int j = 0; j < 4; j++) {
            while (pos[j] < data.size() && data[pos[j]].first == pp[j]) {
                ll s = data[pos[j]].second.first - plus * (j % 2), t = data[pos[j]].second.second - plus * (j % 2);
                comp.push_back(s);
                comp.push_back(t);
                d.push_back(Ti(1, Pi(j, s)));
                d.push_back(Ti(-1, Pi(j, t)));
                pos[j]++;
            }
        }
        sort(comp.begin(), comp.end());
        comp.erase(unique(comp.begin(), comp.end()), comp.end());
        for (int j = 0; j < comp.size(); j++) conv[comp[j]] = j;
        for (int p = 0; p < 4; p++) 
            for (int j = 0; j < comp.size(); j++) 
                sum[p][j] = 0;
        for (int j = 0; j < d.size(); j++) 
            sum[d[j].second.first][conv[d[j].second.second]] += d[j].first;
        for (int j = 0; j < comp.size() - 1; j++) {
            bool flag = true;
            for (int k = 0; k < 4; k++) {
                now[k] += sum[k][j];
                if (now[k] <= 0) flag = false;
            }
            if (flag) ans += comp[j + 1] - comp[j];
        }
        i = pos[0];
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 33196
final_rank: 6

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
using P = pair<int, int>;
typedef struct { ll key; int x, y, v; } T;

// 構造体の高速昇順ソート。ソート対象は key
void usort(T a[], int n) {   // 配列と長さ
#define K 8
#define B 8
#define BMSK 255 // (1<<8)-1
    int i, k;
    int t1[1 << B], t2[1 << B];
    T *tmp = (T *)malloc(n * sizeof(T));
    for (k = 0; k < K; ++k) {
        memset(t1, 0, sizeof(t1)), memset(t2, 0, sizeof(t2));
        for (i = 0; i < n; ++i)	t1[(a[i].key >> k*B) & BMSK]++;
        for (i = 0; i < BMSK; ++i) t1[i+1] += t1[i];
        i = n; while (i--) tmp[--t1[(a[i].key >> k*B) & BMSK]] = a[i];
        k++;
        for (i = 0; i < n; ++i) t2[(tmp[i].key >> k*B) & BMSK]++;
        for (i = 0; i < BMSK; ++i) t2[i+1] += t2[i];
        i = n; while (i--) a[--t2[(tmp[i].key >> k*B) & BMSK]] = tmp[i];
    }
    free(tmp);
    return;
#undef K
#undef B
    for (i = 0; i < n; ++i) printf("[%d] %lld\n", i, a[i].key);
}

T tbl[4*100005]; int sz;
int  N, K;
char S[100005];
map <pair<int, int>, vector<P>> mp;

void setup(int x, int y) {
    for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j) {
        tbl[sz++] = (T){((ll)(x+i) << 32) | (y+j), x+i, y+j, 1<<((i<<1)+j)};
    }
}

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x0 = 100000, x = x0, y0 = 100000, y = y0;
    setup(x, y);
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        setup(x, y);
    }
    if (x == x0+N || x == x0-N || y == y0+N || y == y0-N) { puts("0"); return 0; }

    usort(tbl, sz);
    tbl[sz].key = -1;
    j = 0; for (i = 1; i < sz; ++i) {
        while (tbl[i].key == tbl[j].key) tbl[j].v |= tbl[i++].v;
        if (i < sz && ++j != i) tbl[j] = tbl[i];
    }
    sz = j+1;

    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (i = 0; i < sz; ++i) {
        int c, k = tbl[i].x, l = tbl[i].y, v = tbl[i].v;
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp[P{k,l}].push_back(P{c, v});
        mp[P{k,l}].push_back(P{c+K, -v});
    }

    ll ans = 0;
    for (auto &it: mp) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) { ok = 0; break; }
            if (ok) ans += it2.first - p;
             if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 34796
final_rank: 2

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
using P = pair<int, int>;
typedef struct { ll key; int x, y, v; } T;

// 構造体の高速昇順ソート。ソート対象は key
void usort(T a[], int n) {   // 配列と長さ
#define K 8
#define B 8
#define BMSK 255 // (1<<8)-1
    int i, k;
    int t1[1 << B], t2[1 << B];
    T *tmp = (T *)malloc(n * sizeof(T));
    for (k = 0; k < K; ++k) {
        memset(t1, 0, sizeof(t1)), memset(t2, 0, sizeof(t2));
        for (i = 0; i < n; ++i)	t1[(a[i].key >> k*B) & BMSK]++;
        for (i = 0; i < BMSK; ++i) t1[i+1] += t1[i];
        i = n; while (i--) tmp[--t1[(a[i].key >> k*B) & BMSK]] = a[i];
        k++;
        for (i = 0; i < n; ++i) t2[(tmp[i].key >> k*B) & BMSK]++;
        for (i = 0; i < BMSK; ++i) t2[i+1] += t2[i];
        i = n; while (i--) a[--t2[(tmp[i].key >> k*B) & BMSK]] = tmp[i];
    }
    free(tmp);
    return;
#undef K
#undef B
    for (i = 0; i < n; ++i) printf("[%d] %lld\n", i, a[i].key);
}

T tbl[4*100005]; int sz;
int  N, K;
char S[100005];
map <pair<int, int>, vector<P>> mp;

void setup(int x, int y) {
    for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j) {
        tbl[sz++] = (T){((ll)(x+i) << 32) | (y+j), x+i, y+j, 1<<((i<<1)+j)};
    }
}

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x = 100000, y = 100000;
    setup(x, y);
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        setup(x, y);
    }
    usort(tbl, sz);
    tbl[sz].key = -1;
    j = 0; for (i = 1; i < sz; ++i) {
        while (tbl[i].key == tbl[j].key) tbl[j].v |= tbl[i++].v;
        if (i < sz && ++j != i) tbl[j] = tbl[i];
    }
    sz = j+1;

    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (i = 0; i < sz; ++i) {
        int c, k = tbl[i].x, l = tbl[i].y, v = tbl[i].v;
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp[P{k,l}].push_back(P{c, v});
        mp[P{k,l}].push_back(P{c+K, -v});
    }

    ll ans = 0;
    for (auto &it: mp) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) { ok = 0; break; }
            if (ok) ans += it2.first - p;
             if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 34840
final_rank: 3

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
#define HASHSIZ 9999991
typedef struct { ll a; int id; } HASH;
HASH Hash[HASHSIZ+5];
HASH *hashend = Hash+HASHSIZ;

void insert(ll a, int id) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return;
        if (++p == hashend) p = Hash;
    }
    p->a = a, p->id = id;
}

int lookup(ll a) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return p->id;
        if (++p == hashend) p = Hash;
    }
    return -1;
}

using P = pair<int, int>;
int  N, K;
char  S[100005];
int idx[210000], idy[210000], val[210000], sz;
int tbl[16] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
map <pair<int, int>, vector<P>> mp;

void setup(int x, int y, int v) {
    ll a = ((ll)x << 19) | y;
    int i = lookup(a);
    if (i < 0) i = sz++, idx[i] = x, idy[i] = y, insert(a, i);
    val[i] |= v;
}

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x = 100000, y = 100000;
    for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    }
//printf("sz=%d\n", sz);
    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (i = 0; i < sz; ++i) {
        int c, k = idx[i], l = idy[i], v = val[i];
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp[P{k,l}].push_back(P{c, v});
        mp[P{k,l}].push_back(P{c+K, -v});
    }

    ll ans = 0;
    for (auto &it: mp) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) { ok = 0; break; }
            if (ok) ans += it2.first - p;
             if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 178520
final_rank: 17

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
#define HASHSIZ 8999993 // 4000081 // 2000081
typedef struct { ll a; int id; } HASH;
HASH Hash[HASHSIZ+5];
HASH *hashend = Hash+HASHSIZ;

void insert(ll a, int id) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return;
        if (++p == hashend) p = Hash;
    }
    p->a = a, p->id = id;
}

int lookup(ll a) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return p->id;
        if (++p == hashend) p = Hash;
    }
    return -1;
}

using P = pair<int, int>;
int  N, K;
char S[100005];
int idx[210000], idy[210000], val[210000], sz;
map <pair<int, int>, vector<P>> mp;

void setup(int x, int y, int v) {
    ll a = ((ll)x << 32) | y;
    int i = lookup(a);
    if (i < 0) i = sz++, idx[i] = x, idy[i] = y, insert(a, i);
    val[i] |= v;
}

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x = 100000, y = 100000;
    for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    }
//printf("sz=%d\n", sz);
    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (i = 0; i < sz; ++i) {
        int c, k = idx[i], l = idy[i], v = val[i];
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp[P{k,l}].push_back(P{c, v});
        mp[P{k,l}].push_back(P{c+K, -v});
    }

    ll ans = 0;
    for (auto &it: mp) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) ok = 0;
            if (ok) ans += it2.first - p;
            if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 163596
final_rank: 14

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
#define HASHSIZ 2000081
typedef struct { ll a; int id; } HASH;
HASH Hash[HASHSIZ+5];
HASH *hashend = Hash+HASHSIZ;

void insert(ll a, int id) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return;
        if (++p == hashend) p = Hash;
    }
    p->a = a, p->id = id;
}

int lookup(ll a) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return p->id;
        if (++p == hashend) p = Hash;
    }
    return -1;
}

using P = pair<int, int>;
int  N, K;
char S[100005];
int idx[210000], idy[210000], val[210000], sz;
map <pair<int, int>, vector<P>> mp;

void setup(int x, int y, int v) {
    ll a = ((ll)x << 32) | y;
    int i = lookup(a);
    if (i < 0) i = sz++, idx[i] = x, idy[i] = y, insert(a, i);
    val[i] |= v;
}

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x = 100000, y = 100000;
    for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    }
//printf("sz=%d\n", sz);
    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (i = 0; i < sz; ++i) {
        int c, k = idx[i], l = idy[i], v = val[i];
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp[P{k,l}].push_back(P{c, v});
        mp[P{k,l}].push_back(P{c+K, -v});
    }

    ll ans = 0;
    for (auto &it: mp) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) ok = 0;
            if (ok) ans += it2.first - p;
            if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 54552
final_rank: 13

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
#define HASHSIZ 1000033 //2000081
typedef struct { ll a; int id; } HASH;
HASH Hash[HASHSIZ+5];
HASH *hashend = Hash+HASHSIZ;

void insert(ll a, int id) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return;
        if (++p == hashend) p = Hash;
    }
    p->a = a, p->id = id;
}

int lookup(ll a) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return p->id;
        if (++p == hashend) p = Hash;
    }
    return -1;
}

using P = pair<int, int>;
int  N, K;
char S[100005];
ll id[300000]; int val[300000], sz;
map <pair<int, int>, vector<P>> mp;

void setup(int x, int y, int v) {
    ll a = ((ll)x << 32) | y;
    int i = lookup(a);
    if (i < 0) i = sz++, id[i] = a, insert(a, i);
    val[i] |= v;
}

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x = 100000, y = 100000;
    for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    }
//printf("sz=%d\n", sz);
    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (i = 0; i < sz; ++i) {
        int c, k = (int)(id[i] >> 32), l = (int)(id[i] & 0x7ffffff), v = val[i];
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp[P{k,l}].push_back(P{c, v});
        mp[P{k,l}].push_back(P{c+K, -v});
    }

    ll ans = 0;
    for (auto &it: mp) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) ok = 0;
            if (ok) ans += it2.first - p;
            if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 39496
final_rank: 18

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
#define HASHSIZ 2000081
typedef struct { ll a; int v; } HASH;
HASH Hash[HASHSIZ+5];
HASH *hashend = Hash+HASHSIZ;

void insert(ll a, int v) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) { p->v = v; return; }
        if (++p == hashend) p = Hash;
    }
    p->a = a, p->v = v;
}

int lookup(ll a) {
    HASH *p = Hash + (int)(a % HASHSIZ);
    while (p->a) {
        if (p->a == a) return p->v;
        if (++p == hashend) p = Hash;
    }
    return -1;
}

using P = pair<int, int>;
int  N, K;
char S[100005];
ll pool[300000]; int sz;
map <pair<int, int>, vector<P>> mp;

void setup(int x, int y, int v) {
    ll a = ((ll)x << 32) | y;
    int val = lookup(a);
    if (val < 0) val = 0, pool[sz++] = a;
    insert(a, val | v);
}

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x = 100000, y = 100000;
    for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) setup(x+i, y+j, 1<<((i<<1)+j));
    }

    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (i = 0; i < sz; ++i) {
        int c, k = (int)(pool[i] >> 32), l = (int)(pool[i] & 0x7ffffff);
        int v = lookup(pool[i]);
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp[P{k,l}].push_back(P{c, v});
        mp[P{k,l}].push_back(P{c+K, -v});
    }

    ll ans = 0;
    for (auto &it: mp) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) ok = 0;
            if (ok) ans += it2.first - p;
            if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 290
memory_kb: 53672
final_rank: 16

code_snippet: // AOJ 628 Territory
// 2024.1.18

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()

int in() {   // 非負整数の入力
    int n = 0; int c = gc();
    do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
    return n;
}

void ins(char *s) { // 文字列の入力　スペース以下の文字で入力終了
    do *s = gc();
    while (*s++ > ' ');
    *(s-1) = 0;
}

typedef long long ll;
using P = pair<int, int>;
int  N, K;
char S[100005];
map <pair<int, int>, int> mp1;
map <pair<int, int>, vector<P>> mp2;

int main() {
    int i, j, k;
    N = in(), K = in();
    ins(S);
    int x = 100000, y = 100000;
    for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) mp1[P{x+i, y+j}] |= 1<<((i<<1)+j);
    for (k = 0; k < N; ++k) {
        if      (S[k] == 'E') x++;
        else if (S[k] == 'N') y--;
        else if (S[k] == 'W') x--;
        else                  y++;
        for (i = 0; i < 2; ++i) for (j = 0; j < 2; ++j) mp1[P{x+i,y+j}] |= 1<<((i<<1)+j);
    }
    x -= 100000;
    y -= 100000;
    if (x == 0 && y == 0) K = 1;
    for (auto &it: mp1) {
        int l, c;
        tie(k,l) = it.first;
        if (x) c = k/x, l -= c*y, k %= x;
        else if (y) c = l/y, l %= y;
        else c = 0;
        mp2[P{k,l}].push_back(P{c, it.second});
        mp2[P{k,l}].push_back(P{c+K, -it.second});
    }
    ll ans = 0;
    for (auto &it: mp2) {
        sort(it.second.begin(), it.second.end());
        int u[4] = {0}, p = 0;
        for (auto &it2: it.second) {
            int ok = 1;
            for (i = 0; i < 4; ++i) if (u[i] == 0) ok = 0;
            if (ok) ans += it2.first - p;
            if (it2.second < 0) {
                for (i = 0; i < 4; ++i) u[i] -= ((-it2.second) >> i) & 1;
            } else {
                for (i = 0; i < 4; ++i) u[i] += (it2.second >> i) & 1;
            }
            p = it2.first;
        }
    }
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 37964
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lint = long long;
#define rep(i, n) for(int i = 0; i < int(n); i++)
#define rep2(i, l, n) for(int i = int(l); i < int(n); i++)
#define repr(i, n) for(int i = int(n) - 1; i >= 0; i--)
#define repr2(i, l, n) for(int i = int(n) - 1; i >= int(l); i--)

struct range{
    lint l, r; // [l, r)
};

range AND(range a, range b){
    lint l = max(a.l, b.l);
    lint r = min(a.r, b.r);
    if(l > r) r = l;
    return {l, r};
}

vector<range> OR(vector<range> a){
    int n = int(a.size());
    sort(a.begin(), a.end(), [](range s, range t){ return s.l < t.l; });
    
    vector<range> ret;
    if(a.empty()) return ret;
    
    lint l = a[0].l, r = a[0].r;
    rep2(i, 1, n){
        if(a[i].l <= r){
            r = max(r, a[i].r);
        }else{
            ret.push_back({l, r});
            l = a[i].l;
            r = a[i].r;
        }
    }
    ret.push_back({l, r});
    
    return ret;
}

vector<range> ANDs(vector<range> a, vector<range> b){
    if(a.empty() || b.empty()) return vector<range>(0);
    
    a = OR(a), b = OR(b);
    
    lint l_inf = -1e18, r_inf = 1e18;
    vector<range> nots;
    
    lint l = l_inf, r = -1;
    rep(i, a.size()){
        r = a[i].l;
        nots.push_back({l, r});
        l = a[i].r;
    }
    nots.push_back({l, r_inf});
    
    l = l_inf, r = -1;
    rep(i, b.size()){
        r = b[i].l;
        nots.push_back({l, r});
        l = b[i].r;
    }
    nots.push_back({l, r_inf});
    
    nots = OR(nots);
    
    vector<range> ret;
    rep(i, int(nots.size()) - 1){
        ret.push_back({nots[i].r, nots[i + 1].l});
    }
    return ret;
}

lint solve(map<pair<int, int>, vector<range>> pts){
    set<pair<int, int>> kouho;
    for(auto v: pts){
        auto p = v.first;
        rep(i, 2) rep(j, 2){
            kouho.insert(make_pair(p.first - i, p.second - j));
        }
    }
    
    lint ans = 0;
    for(auto p: kouho){
        vector<vector<range>> ranges;
        rep(i, 2) rep(j, 2){
            ranges.push_back(pts[{p.first + i, p.second + j}]);
        }
        
        vector<range> res = ranges[0];
        rep2(i, 1, 4){
            res = ANDs(res, ranges[i]);
        }
        
        for(auto r: res){
            ans += r.r - r.l;
        }
    }
    
    return ans;
}

int main(){
    int n;
    lint k;
    cin >> n >> k;
    lint x = 0, y = 0;
    vector<pair<lint, lint>> pos{make_pair(0, 0)};
    rep(i, n){
        char c;
        cin >> c;
        if(c == 'E') x++;
        if(c == 'N') y++;
        if(c == 'W') x--;
        if(c == 'S') y--;
        
        pos.push_back({x, y});
    }
    
    if(x == 0 && y == 0){
        map<pair<int, int>, vector<range>> pts;
        for(auto p: pos){
            pts[p].push_back({0, 1});
        }
        
        cout << solve(pts) << endl;
        return 0;
    }
    if(x == 0){
        swap(x, y);
        for(auto &p: pos){
            swap(p.first, p.second);
        }
    }
    if(x > 0){
        x *= -1;
        for(auto &p: pos){
            p.first *= -1;
        }
    }
    if(y > 0){
        y *= -1;
        for(auto &p: pos){
            p.second *= -1;
        }
    }
    
    map<pair<int, int>, vector<range>> pts;
    
    x = abs(x), y = abs(y);
    for(auto p: pos){
        lint to_x = (p.first + lint(1e9) * x) % x;
        
        lint move = (to_x - p.first) / x;
        p.first += move * x;
        p.second += move * y;
        
        pts[p].push_back({move, move + k});
        
//        cout << p.first << " " << p.second << " " << to_x << " -> " << move << endl;
    }
    
    for(auto v: pts){
        auto p = v.first;
        if(p.first > 0) continue;
        
        p.first += x;
        p.second += y;
        for(auto &r: v.second){
            r.l++;
            r.r++;
        }
        
        pts[p] = v.second;
    }
    
    cout << solve(pts) << endl;
}
accuracy: 1
time_ms: 280
memory_kb: 57752
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
template <typename T> using lim = numeric_limits<T>;
struct event {
    bool open;
    int t, dx, dy;
};
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    int a = 0, b = 0;
    set<pair<int, int>> visited({{0, 0}});
    for(int i = 0; i < n; i++) {
        a += (s[i] == 'E') - (s[i] == 'W');
        b += (s[i] == 'N') - (s[i] == 'S');
        visited.insert({a, b});
    }
    if(a == 0 and b == 0) {
        int ans = 0;
        for(auto& p : visited) {
            ans += visited.count({p.first + 1, p.second})
                and visited.count({p.first, p.second + 1})
                and visited.count({p.first + 1, p.second + 1});
        }
        cout << ans << endl;
    } else {
        auto flip_all = [](string& s, char a, char b) {
            for(char& c : s) {
                if(c == a) {
                    c = b;
                } else if(c == b) {
                    c = a;
                }
            }
        };
        if(a < 0) flip_all(s, 'E', 'W');
        if(b < 0) flip_all(s, 'N', 'S');
        a = abs(a), b = abs(b);
        vector<pair<int, int>> pts = {{0, 0}};
        for(int i = 0; i < n - 1; i++) {
            pts.push_back({
                pts.back().first + (s[i] == 'E') - (s[i] == 'W'),
                pts.back().second + (s[i] == 'N') - (s[i] == 'S')
            });
        }
        map<pair<int, int>, vector<pair<int, int>>> rays;
        for(auto& p : pts) {
            int L = a ? p.first / a - (p.first % a < 0): p.second / b, R = L + k - (p.first or p.second);
            int x = a ? (p.first % a + a) % a: p.first, y = p.second - L * b;
            rays[{x, y}].push_back({L, R});
        }
        ll ans = 0;
        for(auto& r : rays) {
            int x, y; tie(x, y) = r.first;
            vector<event> events;
            for(int dx = 0; dx <= 1; dx++) {
                for(int dy = 0; dy <= 1; dy++) {
                    int dL = a ? (x + dx) / a : (y + dy) / b;
                    int nx = a ? (x + dx) % a : (x + dx);
                    int ny = (y + dy) - dL * b;
                    if(rays.count({nx, ny})) {
                        for(auto& p : rays[{nx, ny}]) {
                            int L, R; tie(L, R) = p;
                            events.push_back({true, L - dL, dx, dy});
                            events.push_back({false, R - dL, dx, dy});
                        }
                    } else if(dx == a and dy == b) {
                        for(auto& p : rays[{x, y}]) {
                            int L, R; tie(L, R) = p;
                            events.push_back({true, L, dx, dy});
                            events.push_back({false, R, dx, dy});
                        }
                    }
                }
            }
            sort(events.begin(), events.end(), [](auto& e1, auto& e2) {
                return e1.t < e2.t or (e1.t == e2.t and e1.open and not e2.open);
            });
            map<pair<int, int>, int> active_rays;
            bool all_active = false;
            int all_active_time = 0;
            for(auto& e : events) {
                if(e.open) {
                    active_rays[{e.dx, e.dy}]++;
                    if(active_rays.size() == 4 and not all_active) {
                        all_active = true;
                        all_active_time = e.t;
                    }
                } else {
                    if(--active_rays[{e.dx, e.dy}] == 0) {
                        if(active_rays.size() == 4 and all_active) {
                            all_active = false;
                            ans += e.t - all_active_time + 1;
                        }
                        active_rays.erase({e.dx, e.dy});
                    }
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 0.54
time_ms: 120
memory_kb: 19480
final_rank: 20

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<unordered_map>
#define mp make_pair 
#define pb push_back
#define lol(i,n) for(int i=0;i<n;i++)
#define mod 1000000007
typedef long long ll;

using namespace std;
typedef pair<ll,ll> P;
struct Ver{
    ll x,y;
    bool operator==(const Ver&key)const{
	return key.x==this->x&&key.y==this->y;
    }
    bool operator!=(const Ver&key)const{
	return !(this->operator==(key));
    }
    struct Hash{
	ll operator()(const Ver&key)const{
	    return key.x*mod+key.y;
	}
    };
    Ver(ll x,ll y){this->x=x,this->y=y;}
};
unordered_map<Ver,vector<P>,Ver::Hash> mas,rng;
#define N 200010
ll n,k,x[N],y[N];

int main(){
    cin>>n>>k;
    string s;cin>>s;
    ll a=0,b=0;
    lol(i,n){
	x[i]=a,y[i]=b;
	int dx[]={1,0,-1,0},dy[]={0,-1,0,1};
	char z[]={'E','N','W','S'};
	lol(r,4)if(z[r]==s[i])a+=dx[r],b+=dy[r];
    }
    if(a==0&&b==0)k=1,a=b=1;
    if(a<0){lol(i,n)x[i]=-x[i];a=-a;}
    if(b<0){lol(i,n)y[i]=-y[i];b=-b;}
    if(a==0&&b>0){
	swap(a,b);
	lol(i,n)swap(x[i],y[i]);
    }
    lol(i,n){
	x[i]+=N,y[i]+=N;
	ll dis=x[i]/a;
	ll wid=k-1+(i==0);
	mas[Ver(x[i]%a,y[i]-dis*b)].pb(mp(dis,dis+wid));
    }
    for(auto it:mas){
	auto ver=it.first;
	auto vec=it.second;
	vector<P> qry;
	for(auto i:vec){
	    qry.pb(mp(i.first,+1));
	    qry.pb(mp(i.second+1,-1));
	}
	sort(qry.begin(),qry.end());
	ll cms=0,left;
	for(auto i:qry){
	    ll tim=i.first,dir=i.second;
	    if(dir==-1){
		cms--;
		if(cms==0)rng[ver].pb(mp(left,tim-1));
	    }
	    if(dir==+1){
		if(cms==0)left=tim;
		cms++;
	    }
	}
    }
    ll ans=0;
    for(auto it:rng){
	auto ver=it.first;
	vector<P> qry;
	ll dx[]={0,1,0,1},dy[]={0,0,1,1};
	lol(r,4){
	    ll xx=ver.x+dx[r];
	    ll yy=ver.y+dy[r];
	    bool over=0;
	    if(xx==a)xx-=a,yy-=b,over=1;
	    if(rng.find(Ver(xx,yy))==rng.end())continue;
	    for(auto i:rng[Ver(xx,yy)]){
		qry.pb(mp(i.first-over,+1));
		qry.pb(mp(i.second-over+1,-1));
	    }
	}
	sort(qry.begin(),qry.end());
	ll cms=0,left;
	for(auto i:qry){
	    ll tim=i.first,dir=i.second;
	    if(dir==-1){
		if(cms==4)ans+=tim-left;
		cms--;
	    }
	    if(dir==+1){
		cms++;
		if(cms==4)left=tim;
	    }
	}
    }
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 25184
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair < ll , ll > Pi;
typedef pair < Pi , Pi > PPi;
typedef pair < ll , Pi > Ti;
const ll LLINF = 1LL << 60;
const int INF = (1 << 30) - 1;

char ch[] = "NESW";
ll dy[] = {-1, 0, 1, 0};
ll dx[] = {0, 1, 0, -1};

ll llabs(ll n) { return (n < 0 ? -n : n); }

ll N, K;
string S;
Pi route[200005];
ll vecy = 0, vecx = 0;
vector < PPi > data;
ll ans = 0;
ll sum[4][200005];
int main()
{
    cin >> N >> K >> S;
    for(int i = 0; i < N; i++) {
        int j = 0;
        while(S[i] != ch[j]) j++;
        vecy += dy[j], vecx += dx[j];
        route[i + 1] = Pi(vecy, vecx);
    }
    route[0] = Pi(INF, 2 * N);
    for(int i = 1; i <= N; i++) {
        if(vecy < 0) route[i].first = -route[i].first;
        if(vecx < 0) route[i].second = -route[i].second;
        if(vecx == 0) swap(route[i].first, route[i].second);
        route[i].first += INF, route[i].second += N * 2;
    }
    vecy = llabs(vecy); vecx = llabs(vecx);
    if(vecx == 0) vecx = vecy, vecy = 0;
    sort(route, route + N + 1);
    if(vecx == 0) {
        for(int i = 0; i <= N;) {
            ll y = route[i].first, x = route[i].second;
            Pi *a = route, *b = route + N + 1;
            if(binary_search(a, b, Pi(y + 1, x)) && binary_search(a, b, Pi(y, x + 1)) && binary_search(a, b, Pi(y + 1, x + 1))) ans++;
            while(i <= N && route[i].first == y && route[i].second == x) i++;
        }
        cout << ans << endl;
        return (0);
    }
    for(int i = 0; i <= N; i++) {
        ll y = route[i].first, x = route[i].second;
        data.push_back(PPi(Pi(y - x / vecx * vecy, x % vecx), Pi(x / vecx, x / vecx + K)));
    }
    sort(data.begin(), data.end());
    data.erase(unique(data.begin(), data.end()), data.end());
    for(int i = 0; i < data.size();) {
        vector < ll > comp;
        vector < Ti > d;
        map < ll, ll > conv;
        
        ll now[4] = {};

        ll r, u, ru;
        ll iy = data[i].first.first, ix = data[i].first.second;
        ll plus = (ix + 1) / vecx;
        Pi pp[4] = {data[i].first, Pi(iy - plus * vecy, (ix + 1) % vecx), Pi(iy + 1, ix), Pi(iy + 1 - plus * vecy, (ix + 1) % vecx)};
        Pi nop = Pi(-LLINF, -LLINF);
        ll pos[4];
        pos[0] = i;
        for(int j = 1; j < 4; j++) pos[j] = lower_bound(data.begin(), data.end(), PPi(pp[j], nop)) - data.begin();
        for(int j = 0; j < 4; j++) {
            while(pos[j] < data.size() && data[pos[j]].first == pp[j]) {
                ll s = data[pos[j]].second.first - plus * (j % 2) , t = data[pos[j]].second.second - plus * (j % 2);
                comp.push_back(s); comp.push_back(t);
                d.push_back(Ti(1, Pi(j, s)));
                d.push_back(Ti(-1, Pi(j, t)));
                pos[j]++;
            }
        }
        sort(comp.begin(), comp.end());
        comp.erase(unique(comp.begin(), comp.end()), comp.end());
        for(int j = 0; j < comp.size(); j++) conv[comp[j]] = j;
        for(int p = 0; p < 4; p++) for(int j = 0; j < comp.size(); j++) sum[p][j] = 0;
        for(int j = 0; j < d.size(); j++) sum[d[j].second.first][conv[d[j].second.second]] += d[j].first;
        for(int j = 0; j < comp.size() - 1; j++) {
            bool flag = true;
            for(int k = 0; k < 4; k++) {
                now[k] += sum[k][j];
                if(now[k] <= 0) flag = false;
            }
            if(flag) ans += comp[j + 1] - comp[j];
        }
        i = pos[0];
    }
    cout << ans << endl;
    return (0);
}
accuracy: 1
time_ms: 140
memory_kb: 25312
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair < ll , ll > Pi;
typedef pair < Pi , Pi > PPi;
typedef pair < ll , Pi > Ti;
const ll LLINF = 1LL << 60;
const int INF = (1 << 30) - 1;

char ch[] = "NESW";
ll dy[] = {-1, 0, 1, 0};
ll dx[] = {0, 1, 0, -1};

ll llabs(ll n) { return (n < 0 ? -n : n); }

ll N, K;
string S;
Pi route[200005];
ll vecy = 0, vecx = 0;
vector < PPi > data;
ll ans = 0;
ll sum[4][200005];
int main()
{
    cin >> N >> K >> S;
    for(int i = 0; i < N; i++) {
        int j = 0;
        while(S[i] != ch[j]) j++;
        vecy += dy[j], vecx += dx[j];
        route[i + 1] = Pi(vecy, vecx);
    }
    route[0] = Pi(INF, 2 * N);
    for(int i = 1; i <= N; i++) {
        if(vecy < 0) route[i].first = -route[i].first;
        if(vecx < 0) route[i].second = -route[i].second;
        if(vecx == 0) swap(route[i].first, route[i].second);
        route[i].first += INF, route[i].second += N * 2;
    }
    vecy = llabs(vecy); vecx = llabs(vecx);
    if(vecx == 0) vecx = vecy, vecy = 0;
    sort(route, route + N + 1);
    if(vecx == 0) {
        for(int i = 0; i <= N;) {
            ll y = route[i].first, x = route[i].second;
            if(binary_search(route, route + N + 1, Pi(y + 1, x)) && binary_search(route, route + N + 1, Pi(y, x + 1)) && binary_search(route, route + N + 1, Pi(y + 1, x + 1))) ans++;
            while(i <= N && route[i].first == y && route[i].second == x) i++;
        }
        cout << ans << endl;
        return (0);
    }
    for(int i = 0; i <= N; i++) {
        ll y = route[i].first, x = route[i].second;
        data.push_back(PPi(Pi(y - x / vecx * vecy, x % vecx), Pi(x / vecx, x / vecx + K)));
    }
    sort(data.begin(), data.end());
    data.erase(unique(data.begin(), data.end()), data.end());
    for(int i = 0; i < data.size();) {
        vector < ll > comp;
        vector < Ti > d;
        map < ll, ll > conv;

        ll now[4] = {};

        ll r, u, ru;
        ll iy = data[i].first.first, ix = data[i].first.second;
        ll plus = (ix + 1) / vecx;
        Pi rp = Pi(iy - plus * vecy, (ix + 1) % vecx);
        Pi up = Pi(iy + 1, ix);
        Pi rup = Pi(iy + 1 - plus * vecy, (ix + 1) % vecx);
        Pi ip = data[i].first;
        Pi nop = Pi(-LLINF, -LLINF);

        r = lower_bound(data.begin(), data.end(), PPi(rp, nop)) - data.begin();
        u = lower_bound(data.begin(), data.end(), PPi(up, nop)) - data.begin();
        ru = lower_bound(data.begin(), data.end(), PPi(rup, nop)) - data.begin();
        while(i < data.size() && data[i].first == ip) {
            ll s = data[i].second.first, t = data[i].second.second;
            comp.push_back(s); comp.push_back(t);
            d.push_back(Ti(1, Pi(0, s)));
            d.push_back(Ti(-1, Pi(0, t)));
            i++;
        }
        while(r < data.size() && data[r].first == rp) { 
            ll s = data[r].second.first - plus, t = data[r].second.second - plus;
            comp.push_back(s); comp.push_back(t);
            d.push_back(Ti(1, Pi(1, s)));
            d.push_back(Ti(-1, Pi(1, t)));
            r++;
        }
        while(u < data.size() && data[u].first == up) { 
            ll s = data[u].second.first, t = data[u].second.second;
            comp.push_back(s); comp.push_back(t);
            d.push_back(Ti(1, Pi(2, s)));
            d.push_back(Ti(-1, Pi(2, t)));
            u++;
        }
        while(ru < data.size() && data[ru].first == rup) { 
            ll s = data[ru].second.first - plus, t = data[ru].second.second - plus;
            comp.push_back(s); comp.push_back(t);
            d.push_back(Ti(1, Pi(3, s)));
            d.push_back(Ti(-1, Pi(3, t)));
            ru++;
        }
        sort(comp.begin(), comp.end());
        comp.erase(unique(comp.begin(), comp.end()), comp.end());
        for(int j = 0; j < comp.size(); j++) conv[comp[j]] = j;
        for(int p = 0; p < 4; p++) for(int j = 0; j < comp.size(); j++) sum[p][j] = 0;
        for(int j = 0; j < d.size(); j++) sum[d[j].second.first][conv[d[j].second.second]] += d[j].first;
        for(int j = 0; j < comp.size() - 1; j++) {
            bool flag = true;
            for(int k = 0; k < 4; k++) {
                now[k] += sum[k][j];
                if(now[k] <= 0) flag = false;
            }
            if(flag) ans += comp[j + 1] - comp[j];
        } 
    }
    cout << ans << endl;
    return (0);
}
accuracy: 1
time_ms: 160
memory_kb: 25272
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define int long long
#define INF 1000000000
using namespace std;

typedef pair<int,int> P;

map<P,vector<P> > mp;

signed main(){
	int n,k,x = 0,y = 0,ans = 0;
	P ps[100010];
	string s;
	cin >> n >> k >> s;
	ps[0] = P(0,0);
	for(int i = 0;i < n;i++){
		if(s[i] == 'N') x--;
		else if(s[i] == 'E') y--;
		else if(s[i] == 'W') y++;
		else x++;
		ps[i + 1] = P(x,y);
	}
	for(int i = 0;i <= n;i++){
		if(ps[n].first < 0) ps[i].first *= -1;
		if(ps[n].second < 0) ps[i].second *= -1;
	}
	for(int i = 0;i <= n;i++){
		if(ps[n].first > ps[n].second) swap(ps[i].first,ps[i].second);
	}
	x = ps[n].first;
	y = ps[n].second;
	set<P> st;
	for(int i = 0;i <= n;i++) st.insert(ps[i]);
	if(ps[n] == P(0,0)){
		for(auto it = st.begin();it != st.end();it++){
			bool flag = true;
			for(int j = 0;j < 2;j++){
				for(int k = 0;k < 2;k++){
					if(!st.count(P((*it).first + j,(*it).second + k))) flag = false;
				}
			}
			if(flag) ans++;
		}
		cout << ans << endl;
		return 0;
	}
	for(auto it = st.begin();it != st.end();it++){
		int a = INF,b = INF,d;
		P p = *it;
		if(x) a = (p.first + INF * x) / x - INF;
		if(y) b = (p.second + INF * y) / y - INF;
		d = min(a,b);
		mp[P(p.first - x * d,p.second - y * d)].push_back(P(d,d + k));
	}
	for(auto it = mp.begin();it != mp.end();it++){
		P p = it->first;
		vector<P> vec;
		for(int i = 0;i < 2;i++){
			for(int j = 0;j < 2;j++){
				int nx = p.first + i,ny = p.second + j,a = INF,b = INF,d;
				if(x) a = (nx + INF * x) / x - INF;
				if(y) b = (ny + INF * y) / y - INF;
				d = min(a,b);
				if(mp.find(P(nx - x * d,ny - y * d)) == mp.end()) continue;
				for(P pp : mp[P(nx - x * d,ny - y * d)]){
					vec.push_back(P(pp.first - d,i * 2 + j + 1));
					vec.push_back(P(pp.second - d,-(i * 2 + j + 1)));
				}
			}
		}
		sort(vec.begin(),vec.end());
		int cnt[4] = {},prev;
		for(int i = 0;i < vec.size();i++){
			P pp = vec[i];
			int a = pp.first,b = pp.second;
			bool flag = true;
			for(int j = 0;j < 4;j++) if(!cnt[j]) flag = false;
			if(flag) ans += a - prev;
			prev = a;
			while(i < vec.size() && vec[i].first == a){
				if(vec[i].second > 0) cnt[vec[i].second - 1]++;
				else cnt[-vec[i].second - 1]--;
				i++;
			}
			i--;
		}
	}
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 22060
final_rank: 4

code_snippet: #include <map>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct query { int x, y, d; };
bool operator< (const query& q1, const query& q2) { return ((1LL * q1.d) << 34) + (q1.x << 17) + q1.y < ((1LL * q2.d) << 34) + (q2.x << 17) + q2.y; }
int N, K, cx, cy, dx[100009], dy[100009], fs[100009], ss[100009], tp[100009], vx[4], vy[4], vd[4]; string s; map<query, vector<int> > p; vector<int> cp, cp2, v[4];
int main() {
	ios::sync_with_stdio(false);
	cin >> N >> K >> s; N += 2;
	char cb = s.back();
	if (cb == 'E') s += "WE";
	if (cb == 'N') s += "SN";
	if (cb == 'W') s += "EW";
	if (cb == 'S') s += "NS";
	for (int i = 0; i < 4; i++) {
		cx = 0, cy = 0;
		for (int j = 0; j < N; j++) {
			if (s[j] == 'E') dx[j] = 1, dy[j] = 0;
			if (s[j] == 'N') dx[j] = 0, dy[j] = 1;
			if (s[j] == 'W') dx[j] = -1, dy[j] = 0;
			if (s[j] == 'S') dx[j] = 0, dy[j] = -1;
			cx += dx[j], cy += dy[j];
		}
		if (cx > 0 && cy >= 0) break;
		if (cx == 0 && cy == 0) {
			N--; K = 1; i = -1;
			continue;
		}
		for (int j = 0; j < N; j++) {
			char sc = s[j];
			if (sc == 'E') s[j] = 'N';
			if (sc == 'N') s[j] = 'W';
			if (sc == 'W') s[j] = 'S';
			if (sc == 'S') s[j] = 'E';
		}
	}
	int ry = (cy ? cy : 1012345678), sx = (N / cx + 2) * cx, sy = (N / ry + 1) * ry, sd = sx / cx - sy / ry, sv = sx / cx;
	for (int i = 0; i < N; i++) {
		p[query{ sx % cx, sy % ry, sx / cx - sy / ry }].push_back(sx / cx);
		sx += dx[i];
		sy += dy[i];
	}
	for (pair<const query, vector<int> > &g : p) {
		sort(g.second.begin(), g.second.end());
		g.second.erase(unique(g.second.begin(), g.second.end()), g.second.end());
	}
	long long ret = 0;
	map<query, vector<int> > pt = p;
	for (pair<query, vector<int> > g : pt) {
		vx[0] = g.first.x; vy[0] = g.first.y; vd[0] = g.first.d;
		vx[1] = g.first.x - 1 + (g.first.x == 0 ? cx : 0); vy[1] = g.first.y; vd[1] = g.first.d - (g.first.x == 0 ? 1 : 0);
		vx[2] = g.first.x; vy[2] = g.first.y - 1 + (g.first.y == 0 ? ry : 0); vd[2] = g.first.d + (g.first.y == 0 ? 1 : 0);
		vx[3] = g.first.x - 1 + (g.first.x == 0 ? cx : 0); vy[3] = g.first.y - 1 + (g.first.y == 0 ? ry : 0); vd[3] = g.first.d - (g.first.x == 0 ? 1 : 0) + (g.first.y == 0 ? 1 : 0);
		for (int i = 0; i < 4; i++) {
			v[i] = p[query{ vx[i], vy[i], vd[i] }];
		}
		if (g.first.x == 0) {
			for (int i = 1; i <= 3; i += 2) {
				for (int j = 0; j < v[i].size(); j++) v[i][j]++;
			}
		}
		cp = v[0];
		for (int i = 1; i < 4; i++) {
			int tpr = merge(cp.begin(), cp.end(), v[i].begin(), v[i].end(), tp) - tp;
			cp.resize(tpr);
			for (int j = 0; j < tpr; j++) cp[j] = tp[j];
		}
		cp2.resize(cp.size());
		for (int i = 0; i < cp.size(); i++) cp2[i] = cp[i] + K;
		int tps = merge(cp.begin(), cp.end(), cp2.begin(), cp2.end(), tp) - tp;
		cp.resize(tps);
		for (int i = 0; i < tps; i++) cp[i] = tp[i];
		cp.erase(unique(cp.begin(), cp.end()), cp.end());
		int sp = cp.size();
		fill(fs, fs + sp, 0);
		for (int i = 0; i < 4; i++) {
			fill(ss, ss + sp, 0);
			for (int j : v[i]) {
				ss[lower_bound(cp.begin(), cp.end(), j) - cp.begin()]++;
				ss[lower_bound(cp.begin(), cp.end(), j + K) - cp.begin()]--;
			}
			int curs = 0;
			for (int j = 0; j < sp; j++) {
				curs += ss[j];
				if (curs >= 1) fs[j]++;
			}
		}
		for (int i = 0; i < sp; i++) {
			if (fs[i] == 4) ret += cp[i + 1] - cp[i];
		}
	}
	cout << ret << endl;
	return 0;
}
accuracy: 0.61
time_ms: 80
memory_kb: 33652
final_rank: 19

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
long long N, K, X[100009], Y[100009], ux[100009], uy[100009], uz[100009], cx, cy; string S;
map<pair<long long, long long>, vector<long long>>T; map<pair<long long, long long>, bool>M;
pair<long long, long long>exchange(long long px, long long py, long long &ps) {
	ps = (px + 1000000000LL * cx) / cx - 1000000000LL;
	long long PX = px - ps*cx;
	long long PY = py - ps*cy;
	return make_pair(PX, PY);
}
int main() {
	cin >> N >> K >> S;
	for (int i = 0; i < N; i++) {
		if (S[i] == 'N')cx--; if (S[i] == 'S')cx++;
		if (S[i] == 'E')cy++; if (S[i] == 'W')cy--;
		X[i + 1] = cx; Y[i + 1] = cy;
	}
	if (cx == 0 && cy == 0) {
		K = 1; cx = 1; cy = 1;
	}
	if (cx == 0) {
		for (int i = 0; i <= N; i++)swap(X[i], Y[i]); swap(cx, cy);
	}
	if (cx < 0) {
		for (int i = 0; i <= N; i++)X[i] *= -1; cx *= -1;
	}
	if (cy < 0) {
		for (int i = 0; i <= N; i++)Y[i] *= -1; cy *= -1;
	}
	for (int i = 0; i <= N; i++) {
		long long V = 0;
		pair<long long, long long> uu = exchange(X[i], Y[i], V);
		ux[i] = uu.first; uy[i] = uu.second; uz[i] = V;
		T[make_pair(ux[i], uy[i])].push_back(V);
	}
	long long ans = 0;
	for (int i = 0; i < N; i++) {
		if (M[make_pair(ux[i], uy[i])] == true)continue;
		vector<long long>A[4]; long long D = 0, DE = 0;
		A[0] = T[exchange(ux[i], uy[i], D)];
		A[1] = T[exchange(ux[i] + 1, uy[i], DE)]; if (D != DE) { for (int i = 0; i < A[1].size(); i++) { A[1][i]--; } }
		A[2] = T[exchange(ux[i], uy[i] + 1, DE)]; if (D != DE) { for (int i = 0; i < A[2].size(); i++) { A[2][i]--; } }
		A[3] = T[exchange(ux[i] + 1, uy[i] + 1, DE)]; if (D != DE) { for (int i = 0; i < A[3].size(); i++) { A[3][i]--; } }
		vector<long long>E;
		for (int j = 0; j < 4; j++) { for (int k = 0; k < A[j].size(); k++) { E.push_back(A[j][k]); E.push_back(A[j][k] + K); } }
		sort(E.begin(), E.end()); E.erase(unique(E.begin(), E.end()), E.end());
		vector<int>ES(E.size() + 1, 0);
		for (int j = 0; j < 4; j++) {
			vector<int>ER(E.size() + 1, 0);
			for (int k = 0; k < A[j].size(); k++) {
				int pos1 = lower_bound(E.begin(), E.end(), A[j][k]) - E.begin();
				int pos2 = lower_bound(E.begin(), E.end(), A[j][k] + K) - E.begin();
				ER[pos1]++; ER[pos2]--;
			}
			for (int j = 1; j < E.size() + 1; j++)ER[j] += ER[j - 1];
			for (int j = 0; j < E.size() + 1; j++) { if (ER[j] >= 1)ES[j] += 1; }
		}
		long long res = 0;
		for (int j = 0; j < E.size(); j++) {
			if (ES[j] == 4)res += (E[j + 1] - E[j]);
		}
		ans += res;
		M[make_pair(ux[i], uy[i])] = true;
	}
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 31844
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;

using LL = long long;
using Point = pair<int, int>;
using Interval = pair<int, int>;
using Event = pair<int, bool>;
const bool IN = false;
const bool OUT = true;

int N, K;
string S;

LL loop(auto& p) {
  set<Point> s(begin(p), end(p));
  LL res = 0;
  for(auto i: s) {
    auto x = i.first, y = i.second;
    if(s.count({x+1, y}) && s.count({x, y+1}) && s.count({x+1, y+1})) ++res;
  }
  return res;
}

LL solve(auto& p, int a, int b) {
  // vectorize
  map<Point, set<Interval>> vec;
  for(auto i: p) {
    auto k = i.first / a;
    auto x = i.first % a;
    auto y = i.second - b * k;
    if(x < 0) {
      --k;
      x += a;
      y += b;
    }
    vec[{x, y}].emplace(k, k + K - 1);
  }

  // merge
  map<Point, set<Event>> event;
  for(auto& i: vec) {
    auto cur = begin(i.second);
    auto l = cur->first, h = cur->second;
    for(auto pre = cur++; pre != end(i.second); pre = cur++) {
      if(cur == end(i.second)) {
        event[i.first].emplace(l, IN);
        event[i.first].emplace(h, OUT);
        break;
      }
      if(cur->first - 1 <= pre->second) h = cur->second;
      else {
        event[i.first].emplace(l, IN);
        event[i.first].emplace(h, OUT);
        l = cur->first;
        h = cur->second;
      }
    }
  }

  // intersect
  LL res = 0;
  for(auto i: event) {
    auto cur = i.first;
    multiset<Event> q;
    for(auto neighbor: {cur, {cur.first + 1, cur.second}, {cur.first + 1, cur.second + 1}, {cur.first, cur.second + 1}}) {
      auto dif = 0;
      if(neighbor.first >= a) {dif = 1; neighbor = {neighbor.first - a, neighbor.second - b};}
      if(!event.count(neighbor)) break;
      for(auto e: event[neighbor]) q.emplace(e.first - dif, e.second);
    }
    // count
    auto cnt = 0, begin = 0;
    for(auto e: q) {
      if(e.second == IN) {
        ++cnt;
        begin = e.first;
      } else {
        if(cnt == 4) res += e.first - begin + 1;
        --cnt;
      }
    }
  }
  return res;
}

LL solve() {
  // simulate
  auto x = 0, y = 0;
  vector<Point> p;
  p.emplace_back(x, y);
  for(auto i: S) {
    x += (i=='E') - (i=='W');
    y += (i=='N') - (i=='S');
    p.emplace_back(x, y);
  }

  if(x == 0 && y == 0) return loop(p);

  if(x == 0) {swap(x, y); for(auto& i: p) swap(i.first, i.second);}
  if(x < 0) {x *= -1; for(auto& i: p) i.first *= -1;}
  return solve(p, x, y);
}

int main() {
  cin >> N >> K >> S;
  cout << solve() << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 36448
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;

using LL = long long;
using Point = pair<int, int>;
using Interval = pair<int, int>;
using Event = pair<int, bool>;
const bool IN = false;
const bool OUT = true;

int N, K;
string S;

LL loop(auto& p) {
  set<Point> s(begin(p), end(p));
  LL res = 0;
  for(auto i: s) {
    auto x = i.first, y = i.second;
    if(s.count(Point(x+1, y)) && s.count(Point(x, y+1)) && s.count(Point(x+1, y+1))) ++res;
  }
  return res;
}

LL solve(auto& p, int a, int b) {
  // vectorize
  map<Point, set<Interval>> vec;
  for(auto i: p) {
    auto k = i.first / a;
    auto x = i.first % a;
    auto y = i.second - b * k;
    if(x < 0) {
      --k;
      x += a;
      y += b;
    }
    vec[{x, y}].emplace(k, k + K - 1);
  }
//   for(auto i: vec){
//     cout<<i.first.first<<","<<i.first.second<<": ";
//     for(auto j: i.second)cout<<" ["<<j.first<<","<<j.second<<"] ";
//     cout<<endl;
//   }

  // merge
  map<Point, set<Event>> event;
  for(auto& i: vec) {
    auto cur = begin(i.second);
    auto l = cur->first, h = cur->second;
    for(auto pre = cur++; pre != end(i.second); pre = cur++) {
      if(cur == end(i.second)) {
        event[i.first].emplace(l, IN);
        event[i.first].emplace(h, OUT);
        break;
      }
      if(cur->first - 1 <= pre->second) h = cur->second;
      else {
        event[i.first].emplace(l, IN);
        event[i.first].emplace(h, OUT);
        l = cur->first;
        h = cur->second;
      }
    }
  }
//   for(auto i: event) {
//     cout<<i.first.first<<","<<i.first.second<<": ";
//     for(auto j: i.second)cout<<" "<<j.first<<"_"<<j.second<<" ";
//     cout<<endl;
//   }

  // intersect
  LL res = 0;
  for(auto i: event) {
    auto cur = i.first;
//     cout<<res<<endl;
//     cout<<"TRY: "<<cur.first<<","<<cur.second<<endl;
    multiset<Event> q;
    for(auto e: event[cur]) q.emplace(e);
    for(auto nex: {Point(cur.first + 1, cur.second), Point(cur.first + 1, cur.second + 1), Point(cur.first, cur.second + 1)}) {
//       cout<<"  with: "<<nex.first<<","<<nex.second<<endl;
      auto dif = 0;
      if(nex.first >= a) {dif = 1; nex = Point(nex.first - a, nex.second - b);}
//       if(!event.count(nex)) cout<<"NG"<<endl;
      if(!event.count(nex)) break;
      for(auto e: event[nex]) q.emplace(e.first - dif, e.second);
    }
    // count
    auto cnt = 0;
    auto l = 0;
    for(auto e: q) {
      if(e.second == IN) {
        ++cnt;
        l = e.first;
      } else {
        if(cnt == 4) res += e.first - l + 1;
        --cnt;
      }
    }
  }
  return res;
}

LL solve() {
  // simulate
  auto x = 0, y = 0;
  vector<Point> p;
  p.emplace_back(x, y);
  for(auto i: S) {
    x += (i=='E') - (i=='W');
    y += (i=='N') - (i=='S');
    p.emplace_back(x, y);
//     cout<<x<<" "<<y<<endl;
  }

  if(x == 0 && y == 0) return loop(p);

  if(x == 0) {swap(x, y); for(auto& i: p) swap(i.first, i.second);}
  if(x < 0) {x *= -1; for(auto& i: p) i.first *= -1;}
  return solve(p, x, y);
}

int main() {
  cin >> N >> K >> S;
  cout << solve() << endl;
}
accuracy: 1
time_ms: 180
memory_kb: 36468
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;

using LL = long long;
using Point = pair<int, int>;
using Interval = pair<int, int>;
using Event = pair<int, bool>;
const bool IN = false;
const bool OUT = true;

int N, K;
string S;

LL loop(auto& p) {
  set<Point> s(begin(p), end(p));
  LL res = 0;
  for(auto i: s) {
    auto x = i.first, y = i.second;
    res += s.count(Point(x+1, y)) && s.count(Point(x, y+1)) && s.count(Point(x+1, y+1));
  }
  return res;
}

LL solve(auto& p, int a, int b) {
  // vectorize
  map<Point, set<Interval>> vec;
  for(auto i: p) {
    auto k = i.first / a;
    auto x = i.first % a;
    auto y = i.second - b * k;
    if(x < 0) {
      --k;
      x += a;
      y += b;
    }
    vec[{x, y}].emplace(k, k + K - 1);
  }
//   for(auto i: vec){
//     cout<<i.first.first<<","<<i.first.second<<": ";
//     for(auto j: i.second)cout<<" ["<<j.first<<","<<j.second<<"] ";
//     cout<<endl;
//   }

  // merge
  map<Point, set<Event>> event;
  for(auto& i: vec) {
    auto cur = begin(i.second);
    auto l = cur->first, h = cur->second;
    for(auto pre = cur++; pre != end(i.second); pre = cur++) {
      if(cur == end(i.second)) {
        event[i.first].emplace(l, IN);
        event[i.first].emplace(h, OUT);
        break;
      }
      if(cur->first - 1 <= pre->second) h = cur->second;
      else {
        event[i.first].emplace(l, IN);
        event[i.first].emplace(h, OUT);
        l = cur->first;
        h = cur->second;
      }
    }
  }
//   for(auto i: event) {
//     cout<<i.first.first<<","<<i.first.second<<": ";
//     for(auto j: i.second)cout<<" "<<j.first<<"_"<<j.second<<" ";
//     cout<<endl;
//   }

  // unite
  LL res = 0;
  for(auto i: event) {
    auto cur = i.first;
//     cout<<res<<endl;
//     cout<<"TRY: "<<cur.first<<","<<cur.second<<endl;
    multiset<Event> q;
    for(auto e: event[cur]) q.emplace(e);
    for(auto nex: {Point(cur.first + 1, cur.second), Point(cur.first + 1, cur.second + 1), Point(cur.first, cur.second + 1)}) {
//       cout<<"  with: "<<nex.first<<","<<nex.second<<endl;
      auto dif = 0;
      if(nex.first >= a) {dif = 1; nex = Point(nex.first - a, nex.second - b);}
//       if(!event.count(nex)) cout<<"NG"<<endl;
      if(!event.count(nex)) break;
      for(auto e: event[nex]) q.emplace(e.first - dif, e.second);
    }
    // count
    auto cnt = 0;
    auto l = 0;
    for(auto e: q) {
      if(e.second == IN) {
        ++cnt;
        l = e.first;
      } else {
        if(cnt == 4) res += e.first - l + 1;
        --cnt;
      }
    }
  }
  return res;
}

LL solve() {
  // simulate
  auto x = 0, y = 0;
  vector<Point> p;
  p.emplace_back(x, y);
  for(auto i: S) {
    x += (i=='E') - (i=='W');
    y += (i=='N') - (i=='S');
    p.emplace_back(x, y);
//     cout<<x<<" "<<y<<endl;
  }

  if(x == 0 && y == 0) return loop(p);

  if(x < 0) {x *= -1; for(auto& i: p) i.first *= -1;}
  if(y < 0) {y *= -1; for(auto& i: p) i.second *= -1;}
  if(x == 0) {swap(x, y); for(auto& i: p) swap(i.first, i.second);}
  return solve(p, x, y);
}

int main() {
  cin >> N >> K >> S;
  cout << solve() << endl;
}
accuracy: 1
time_ms: 180
memory_kb: 36524
final_rank: 11