Sum Toy:http://codeforces.com/problemset/problem/405/D
题意:说了一个故事,其实就是个特殊加法。翻译下就是:给定一个自然数集合[1,2,..., 1000000],由用户给定一个子集合[x1, x2, ..., xn], 1<=n<=5*1e5 。根据给定公式求 子集合Y 。
公式:
将公式拆开就是:(x1-1)+(x2-1)+(x3-1)+... = (s-y1) + (s-y2) + (s-y3) + ...
推出: (x1 + y1) + (x2 + y2) + (x3 + y3) + .... = n(s + 1)
即: xi + yi ≡ s + 1;
所以,yi 的值将和X的集合分离。
1、求出 X 集合中没有配对元素 xi ,与 xi 对应的 yi 就是Y集合中的一个元素。记录下个数。
2、通过个数控制新数对 xj 和 yj ,并记录个数(两个)
代码:
/* *** * @codeforces problem 405D. Toy Sum * @author:ckeling * @date:2014.3.26 * @tag:greedy, implementation, math ******/ #include <stdio.h> #include <string.h> #define MAXN 1000000 int X[MAXN + 1]; int S[MAXN + 1]; int Y[MAXN + 1]; int main(){ memset(X, 0, sizeof(X)); memset(S, 0, sizeof(S)); memset(Y, 0, sizeof(Y)); int nx, ny; int i; scanf("%d", &nx); for(i = 0; i < nx; ++i){ scanf("%d", X+i); S[X[i]] = 1; } ny = 0; for(i = 0; i < nx; ++i){ if(S[X[i]] && !S[MAXN + 1 - X[i]]){ Y[MAXN + 1 - X[i]] = 1; ny++; } } for(i = 1; i < MAXN && ny < nx; ++i){ if(!S[i] && !S[MAXN + 1 - i]){ Y[i] = 1; ny++; Y[MAXN + 1 - i] = 1; ny++; } } printf("%d\n", ny); for(i = 0; i <= MAXN; ++i) if(Y[i]) printf("%d ", i); return 0; }