Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

完全平等二国間貿易

サイバースペースにあるアイヅ国はワカマツ国と情報貿易を行っています。２つの国はお互いに有用なデータを交換することで経済発展を遂げています。博愛と平等、そして何よりも会津地方の古い言葉である、「ならぬことはならぬものです」を国是とする両国は、定期的に貿易状況の調査を行っています。

調査では、バイト単位でアイヅ国から見たデータ流入量から流出量を引いた値を、１ナノ秒ごとに求めた表が与えられます。その表から、値の総和が０になる最長の区間を見つけます。この区間が長いほど、平等性が保たれていると判断します。

貿易状況が記録された表が与えられたとき、値の総和が０になる最長の区間の長さを求めるプログラムを作成せよ。

Input

入力は以下の形式で与えられる。

N
d1
d2
:
dN

１行目に、表に書かれた値の数 N (1 ≤ N ≤ 200000) が与えられる。続く N 行に、表の i 行目に書かれた値を示す整数 di (-109 ≤ di ≤ 109) が与えられる。

Output

表から得られる、総和が０になる最長の区間の長さを１行に出力する。そのような区間が存在しない場合、「0」を１行に出力する。

Sample Input 1

5
18
102
-155
53
32

Sample Output 1

3

入力例１では、２行目から４行目までの値の総和が０になるので、最長の区間の長さが3になる。

Sample Input 2

4
1
1
-1
-1

Sample Output 2

4

入力例２では、２行目から３行目の総和が０になるが、１行目から４行目までの値の総和も０になるので、最長の区間の長さが4になる。

Solution in C (judge verdict: Accepted)

// AOJ 0329: Bilateral Trade
// 2017.8.26 bal4u@uu
// 2017.11.14

#include <stdio.h>

#define MAX 200000

#define HASHSIZ 370003LL
#define BASE 200000000000001LL        // -200,000 x 10^9
typedef struct { int i; long long s; } HASH;
HASH hash[HASHSIZ+2], *hashend = hash+HASHSIZ;

int insert(int i, long long s)
{
    HASH *p;
    s += BASE;
    p = hash + s % HASHSIZ;
    while (p->s) {
        if (p->s == s) return p->i;
        if (++p == hashend) p = hash;
    }
    p->s = s, p->i = i;
    return -1;
}

char buf[20], *p;
int getint()
{
	int n = 0;
	if (*p == '-') {
		p++; while (*p >= '0') n = (n<<3) + (n<<1) + (*p++ & 0xf);
		return -n;
	}
	while (*p >= '0') n = (n<<3) + (n<<1) + (*p++ & 0xf);
	return n;
}

int main()
{
//  int N, d;
	int N;
    int i, k, max;
    long long s0, s;

//	memset(hash, 0, sizeof(hash));
//  scanf("%d", &N);
	fgets(p=buf, 20, stdin), N = getint();
    insert(0, 0);
    for (max = 0, s0 = 0, i = 1; i <= N; i++, s0 = s) {
//      scanf("%d", &d), s = s0 + d;
		fgets(p=buf, 20, stdin), s = s0 + getint();
        if ((k = insert(i, s)) >= 0) {
            if (i - k > max) max = i - k;
        }
    }
    printf("%d\n", max);
    return 0;
}