http://acm.hdu.edu.cn/showproblem.php?pid=4334
这题开始做的时候,不是O(n^2)*O(logn^3) MLE就是O(n^3)*O(logn^2) TLE了
后来看解题报告都没看懂
幽幽子大神给我讲了下,真的是恍然大悟啊
while(j < cnt1 && k >= 0){ if(f[j] + g[k] == -tmp){ flag = 1; break; } if(f[j] + g[k] < 0 - tmp) j ++; else k --;
}
对于这一段,开始用最小的加最大的,如果和小于要查找的话,那么说明大的不够用,小的就加,即j++
反之就 k--了
给跪子orz
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define ll __int64 ll a[210]; ll b[210]; ll c[210]; ll f[202*202]; ll g[202*202]; int n; int main(){ int tcase; scanf("%d", &tcase); while(tcase --){ scanf("%d", &n); memset(f, 0, sizeof f); memset(g, 0, sizeof g); int cnt1 = 0; int cnt2 = 0; for(int i = 0; i < n; i ++) scanf("%I64d", a + i); for(int i = 0; i < n; i ++) scanf("%I64d", b + i); for(int i = 0; i < n; i ++) scanf("%I64d", c + i); for(int i = 0; i < n; i ++){ for(int j = 0; j < n; j ++){ f[cnt1++] = a[i] + b[j]; } } for(int i = 0; i < n; i ++) scanf("%I64d", a + i); for(int i = 0; i < n; i ++){ for(int j = 0; j < n; j ++){ g[cnt2++] = a[i] + c[j]; } } for(int i = 0; i < n; i ++) scanf("%I64d", c + i); sort(f, f + cnt1); sort(g, g + cnt2); sort(c, c + n); int flag = 0; for(int i = 0; i < n; i ++){ ll tmp = c[i]; int j = 0; int k = cnt2 - 1; while(j < cnt1 && k >= 0){ if(f[j] + g[k] == -tmp){ flag = 1; break; } if(f[j] + g[k] < 0 - tmp) j ++; else k --; } } /* for(int i = 0; i < cnt1; i ++){ for(int j = 0; j < n; j ++){ ll tmp = 0 - f[i] - c[j]; if(tmp < g[0] || tmp > g[cnt2-1])continue; int l = 0, r = cnt2-1; int fl = 0; while(l <= r){ int mid = l + r >> 1; if(g[mid] == tmp){ fl = 1; break; } if(tmp < g[mid]) r = mid-1; else if(tmp > g[mid]) l = mid+1; } if(fl){ flag = 1; break; } } if(flag) break; } */ if(flag) puts("Yes"); else puts("No"); } return 0; }