[CF1478C] Nezzar and Symmetric Array
前言
我可以說這道題是這場 Div2 最難的題嗎?就這道題掛過,還掛了 \(3\) 次!
有趣的做題時間(單位:分鐘):
\(A:3; B:10; C:86; D:11; E:22;\)
F 沒時間做了,痛失AK。1700 的難度你是在逗我?
題目
題目大意: 洛谷。
注意 \(a_i\) 兩兩不同。
講解
首先有一些很顯然的結論: 每種數字出現次數一定是偶數次,並且一定是偶數,互為相反數的兩個數 \(d_i\) 一定相等。
這些結論隨便玩一玩就可以想到。
為了方便講解,我們令 \(-a_n<...<-a_2<-a_1<0<a_1<a_2<...<a_n\)
然後我們開始對題意進行轉換:將 \(a_i\) 放在數軸上,那麼 \(|a_i-a_j|\) 即為兩點之間的距離,\(d_i\) 即為 \(i\) 與其它所有點的距離和。
顯然,越中間的 \(a_i\) 對應的 \(d_i\) 越小,為方便處理,我們可以對 \(d_i\) 進行排序,然後砍掉相同的一半。
我們直接試圖將 \(a_i\) 構造出來,最好下手的是 \(a_n\)。
因為有 \(-a_i\) 的存在,我們在數軸上無論怎麼移動 \(a_i\),對 \(d_n\) 都是沒有影響的!
所以此時 \(a_n=\frac{d_n}{2\times n}\),當然,如果不整除就無解。
那麼 \(a_{n-1}\)
考慮 \(a_n\) 對 \(d_{n-1}\) 的影響是什麼:\(-a_n\) 與 \(a_n\) 將 \(a_{n-1}\) 夾在中間,所以 \(d_{n-1}\) 只需要減去 \(2\times a_n\) 就可以按上述方法接著做了。
需要滿足的條件是 \(a_i>0,i\in[1,n]\) 與 \(a_i<a_{i+1},i\in[1,n-1]\)。當然,上面那個 \(2\times n|d_n\) 也需要滿足。
程式碼
//12252024832524 #include <cstdio> #include <cstring> #include <algorithm> #define TT template<typename T> using namespace std; typedef long long LL; const int MAXN = 200005; LL n; LL d[MAXN],a[MAXN]; LL Read() { LL x = 0,f = 1;char c = getchar(); while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();} return x * f; } TT void Put1(T x) { if(x > 9) Put1(x/10); putchar(x%10^48); } TT void Put(T x,char c = -1) { if(x < 0) putchar('-'),x = -x; Put1(x); if(c >= 0) putchar(c); } TT T Max(T x,T y){return x > y ? x : y;} TT T Min(T x,T y){return x < y ? x : y;} TT T Abs(T x){return x < 0 ? -x : x;} int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); for(int T = Read(); T ;-- T) { n = Read(); for(int i = 1;i <= 2*n;++ i) d[i] = Read(); sort(d+1,d+2*n+1); bool f = 1; for(int i = 1;i <= 2*n && f;i += 2) if(d[i] != d[i+1] || (d[i] & 1)) f = 0; for(int i = 2;i <= 2*n;i += 2) d[i/2] = d[i]; LL jian = 0; a[n+1] = 0; for(int i = n;i >= 1 && f;-- i) { d[i] -= jian; if(d[i] <= 0 || d[i] % (2*n)) {f = 0;break;} a[i] = d[i] / (2*n); if(a[i] == a[i+1]) {f = 0;break;}//pay attention to “distinct”! jian += 2*a[i]; n--; } if(!f) {printf("NO\n");continue;} printf("YES\n"); } return 0; }