题目链接:http://codeforces.com/contest/862/problem/E
题解:水题显然利用前缀和考虑一下然后就是二分b的和与-ans_a最近的数(ans_a表示a的前缀和(奇加偶减))
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; const int M = 1e5 + 10; ll a[M] , b[M] , sum[M] , ans_b[M]; int main() { int n , m , q; scanf("%d%d%d" , &n , &m , &q); for(int i = 1 ; i <= n ; i++) scanf("%lld" , &a[i]); for(int i = 1 ; i <= m ; i++) scanf("%lld" , &b[i]); sum[0] = 0; for(int i = 1 ; i <= m ; i++) { if(i % 2) { sum[i] = sum[i - 1] + b[i]; } else { sum[i] = sum[i - 1] - b[i]; } } for(int i = 1 ; i <= m - n + 1 ; i++) { if(!(i % 2)) { ans_b[i - 1] = sum[i + n - 1] - sum[i - 1]; } else { ans_b[i - 1] = sum[i - 1] - sum[i + n - 1]; } } sort(ans_b , ans_b + m - n + 1); ll ans_a = 0; for(int i = 1 ; i <= n ; i++) { if(i % 2) { ans_a += a[i]; } else { ans_a -= a[i]; } } int pos = 0; pos = lower_bound(ans_b , ans_b + m - n + 1 , -ans_a) - ans_b; pos = min(m - n , pos); printf("%lld " , min(abs(ans_a + ans_b[max(0 , pos - 1)]) , min(abs(ans_a + ans_b[pos]) , abs(ans_a + ans_b[min(m - n , pos + 1)])))); while(q--) { int l , r; ll x; scanf("%d%d%lld" , &l , &r , &x); if(l % 2) { if((r - l + 1) % 2) { ans_a += x; } } else { if((r - l + 1) % 2) { ans_a -= x; } } pos = lower_bound(ans_b , ans_b + m - n + 1 , -ans_a) - ans_b; pos = min(m - n , pos); printf("%lld " , min(abs(ans_a + ans_b[max(0 , pos - 1)]) , min(abs(ans_a + ans_b[pos]) , abs(ans_a + ans_b[min(m - n , pos + 1)])))); } return 0; }