题意:首先给出n个数,和K,然后问有没有一个二元组满足K= SUM(I, J), SUM(I, J) =
ai−ai+1+ai+2+⋯+(−1)j−iaj
首先我们假设存在这样的二元组(i,j)那么该二元组的(i,j)表示的就是一段连续的区间,即区间SUM(i ~ j )= K。那么在这个区间前面的区间就是(1~i-1),设SUM(1~i-1) = x,而这两段区间和就是SUM(1~j) = K + x = y。而SUM(a~b)可以通过处理前缀和得到,即,我们可以得到x和y,这样的话确定K有没有出现过,我们只需判断x(即y-K)在之前的区间里面存不存在即可。而 nlogn的时间只能有一种姿势过,即for的时候set(判断存在过与否)只能进行一次insert和find,两次就会T了
#include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; inline void read(ll &x){int flag = 0;x = 0;char c = getchar();if(c == '-') flag = 1;while(c < '0' || c > '9') {if(c == '-') flag = 1;c = getchar();}while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();if(flag) x = -x;} set <ll> s; LL a[1000005]; int main() { int t, ca = 1; scanf("%d", &t); while(t--) { int n; ll k; scanf("%d %I64d", &n, &k); for(int i = 1; i <= n; i++) { read(a[i]); if(i % 2 == 0) a[i] = -a[i]; } s.clear(); printf("Case #%d: ", ca++); for(int i = 1; i <= n; i++) a[i] += a[i-1]; bool flag = 1; for(int i = n; i >= 0 && flag; i--) { if(i % 2 == 0) { if(s.find(a[i] + k) != s.end()) flag = 0; } else { if(s.find(a[i] - k) != s.end()) flag=0; } s.insert(a[i]); } if(flag) puts("No."); else puts("Yes."); } return 0; }