Trong một basic block gồm n lệnh ba địa chỉ dạng t = a op b (op ∈ {+, -, *, /}), áp dụng kỹ thuật đánh số giá trị cục bộ (local value numbering) để phát hiện biểu thức con chung (common subexpression) có thể loại bỏ.
Với phép + và * (giao hoán), a op b và b op a tạo ra cùng một giá trị. Với - và /, thứ tự toán hạng có ý nghĩa (không hoán đổi). Toán hạng a, b có thể là tên biến hoặc hằng số nguyên.
Quy tắc đánh số:
t = a op b: lấy VN hiện tại của a, b (theo trạng thái ngay TRƯỚC lệnh i), tạo khóa (op, VN(a), VN(b)) (không phân biệt thứ tự nếu op giao hoán). Nếu khóa này đã xuất hiện ở lệnh j<i: lệnh i là dư thừa, gán cho t VN giống hệt kết quả của lệnh j, in CSE j. Ngược lại: cấp VN hoàn toàn mới cho biểu thức, lưu khóa lại, gán cho t, in NEW.t (dù NEW hay CSE) LUÔN cập nhật VN hiện tại của biến t cho các lệnh sau.Sau khi in xong n dòng kết quả, in thêm dòng cuối SAVED=k với k là tổng số lệnh được xác định là CSE (dư thừa, có thể loại bỏ).
Input:
4
t1 = a + b
t2 = b + a
t3 = a - b
t4 = b - a
Output:
NEW
CSE 1
NEW
NEW
SAVED=1
(t2 = b + a trùng giá trị với t1 = a + b do + giao hoán; t3, t4 dùng - không giao hoán nên là hai giá trị khác nhau.)
Dòng đầu: số nguyên n (1≤n≤2000). n dòng tiếp theo, mỗi dòng dạng t = a op b, cách nhau đúng 1 khoảng trắng; op ∈ {+, -, *, /}; t luôn là tên biến; a, b là tên biến hoặc hằng số nguyên trong [−1000,1000]. Tên biến gồm chữ thường và chữ số, bắt đầu bằng chữ cái.
In n dòng, mỗi dòng NEW hoặc CSE j (j là chỉ số 1-based của lệnh trùng giá trị sớm nhất), rồi một dòng cuối SAVED=k.
Ví dụ:
Đầu vào:
1
t = a + b
Đầu ra:
NEW
SAVED=0
Đầu vào:
4
t1 = a + b
t2 = b + a
t3 = a - b
t4 = b - a
Đầu ra:
NEW
CSE 1
NEW
NEW
SAVED=1
Đang tải editor...