3067:Japan
keyword
2部グラフ 累積和 C++
概要
2部グラフ(1000*1000以下)が与えられる。ノードを番号順に並べたとき、辺の交点がいくつできるか求める問題。
いもす先生に教えてもらった。2次元配列a[n][m](a[i][j] = exist (i,j) in E)とする。その後各辺に対して、
図の斜線部の和を加算していく。加算は前処理で2次元累積和を計算しておくことにより定数時間で求まる。最後に重複がある分2で割れば答えが求まる。
static int accum[1010][1010]; static int xs[1000010], ys[1000010]; int main(){ int i, j, x, y, n, m, k; int rept; rept = readint(); LOOP(rept){ n = readint(), m = readint(), k = readint(); REP(i,n+1)REP(j,m+1) accum[i][j] = 0; REP(i,k){ ys[i] = readint(); xs[i] = readint(); accum[ys[i]][xs[i]]++; } REPONE(i,n)REPONE(j,m){ accum[i][j] += accum[i-1][j] + accum[i][j-1] - accum[i-1][j-1]; } ll ans = 0; REP(i,k){ x = xs[i]; y = ys[i]; ans += accum[y-1][m] - accum[y-1][x] + accum[n][x-1] - accum[y][x-1]; } printf("Test case %d: %lld\n",loopCount, ans/2); } return 0; }