生活随笔
收集整理的這篇文章主要介紹了
Codeforces Round #670 (Div. 2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
A - Subset Mex
知道NIM游戲應該都知道Mex。那就直接貪心分組,保證盡可能每組都存在每一個自然數,然后按照Mex定義直接求答案即可
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std
;
const int N
=110;
int n
;
int cnt1
[N
],cnt2
[N
];
int main()
{IO
;int T
=1;cin
>>T
;while(T
--){cin
>>n
;memset(cnt1
,0,sizeof cnt1
);memset(cnt2
,0,sizeof cnt2
);for(int i
=1;i
<=n
;i
++) {int a
;cin
>>a
;if(cnt1
[a
])cnt2
[a
]++;elsecnt1
[a
]++;}int res
=0;for(int i
=0;i
<=100;i
++)if(!cnt1
[i
]){res
+=i
;break;}for(int i
=0;i
<=100;i
++)if(!cnt2
[i
]){res
+=i
;break;}cout
<<res
<<endl
;}return 0;
}
B - Maximum Product
由于最終選出的數非常少,因此可以枚舉選出多少個負數,剩下的選非負數。
如果最終結果可以為正數那么就選擇絕對值盡量大的數,否則選擇絕對值盡量小的數。
最終結果一定是負數的條件:①沒有正數②n=5n=5n=5并且負數個數是奇數個
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std
;
typedef long long ll
;
typedef pair
<ll
,ll
> pll
;
typedef pair
<int,int> pii
;
const int N
=100010;
int n
;
ll a
[N
];
ll b
[N
],c
[N
];
int cntb
,cntc
;
int main()
{IO
;int T
=1;cin
>>T
;while(T
--){cin
>>n
;cntb
=cntc
=0;for(int i
=1;i
<=n
;i
++) {cin
>>a
[i
];if(a
[i
]<0) b
[++cntb
]=a
[i
];else c
[++cntc
]=a
[i
];}sort(b
+1,b
+1+cntb
);sort(c
+1,c
+1+cntc
);reverse(c
+1,c
+1+cntc
);ll res
=-1e18;if(cntc
==0||(cntc
==2&&n
==5)||(cntc
==4&&n
==5)){reverse(c
+1,c
+1+cntc
);reverse(b
+1,b
+1+cntb
);}for(int i
=0;i
<=min(cntb
,5);i
++){int j
=5-i
;if(j
>cntc
) continue;ll now
=1;if(i
){for(int k
=1;k
<=i
;k
++) now
*=b
[k
];}if(j
){for(int k
=1;k
<=j
;k
++) now
*=c
[k
];}res
=max(res
,now
);}cout
<<res
<<endl
;}return 0;
}
C - Link Cut Centroids
- 如果重心只有一個,隨便斷一條邊再連上。
- 如果重心有兩個,那么必定相鄰,不難猜想出只要把其中的一個重心連接的葉子接到另一個重心去即可。(貌似把其他一個重心的子樹接到另一個重心也可以)
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std
;
const int N
=100010;
int n
;
int h
[N
],e
[2*N
],ne
[2*N
],idx
;
int sz
[N
];
vector
<int> cnt
;
void add(int a
,int b
)
{e
[idx
]=b
;ne
[idx
]=h
[a
];h
[a
]=idx
++;
}
int fa
[N
];
void dfs1(int u
,int p
)
{fa
[u
]=p
;sz
[u
]=1;int mx
=0;for(int i
=h
[u
];i
!=-1;i
=ne
[i
]){int j
=e
[i
];if(j
==p
) continue;dfs1(j
,u
);sz
[u
]+=sz
[j
];mx
=max(sz
[j
],mx
);}mx
=max(mx
,n
-sz
[u
]);if(2*mx
<=n
) cnt
.push_back(u
);
}
int now
;
int x
,y
;
void dfs2(int u
,int c
)
{if(now
) return;int d
=0;for(int i
=h
[u
];i
!=-1;i
=ne
[i
]){int j
=e
[i
];if(j
==fa
[u
]||j
==c
) continue;d
++;dfs2(j
,c
);}if(d
==0){x
=u
;y
=fa
[u
];now
++;return;}
}
int main()
{IO
;int T
=1;cin
>>T
;while(T
--){cin
>>n
;for(int i
=1;i
<=n
;i
++) h
[i
]=-1;cnt
.clear();idx
=now
=0;for(int i
=1;i
<n
;i
++){int a
,b
;cin
>>a
>>b
;add(a
,b
),add(b
,a
);}dfs1(1,0);if(cnt
.size()==1){dfs2(cnt
[0],cnt
[1]);cout
<<x
<<' '<<y
<<endl
;cout
<<x
<<' '<<y
<<endl
;}else{dfs2(cnt
[0],cnt
[1]);cout
<<x
<<' '<<y
<<endl
;cout
<<x
<<' '<<cnt
[1]<<endl
;}}return 0;
}
就做了上面三個題1h,竟然還上分了!可能我分數比較低把。。B w了2次,C w了1次。。
D - Three Sequences
大佬題解
{b2=b1+Δ1(Δ1≥0)b1+c1=a1b2+c2=a2c1≥c2\begin{cases} b_2=b_1+\Delta_1(\Delta_1 \ge0) \\ b_1+c_1=a_1 \\ b_2+c_2=a_2 \\ c_1\ge c_2\end{cases}??????????b2?=b1?+Δ1?(Δ1?≥0)b1?+c1?=a1?b2?+c2?=a2?c1?≥c2??由上述條件可以推出Δ1\Delta_1Δ1?與a1a_1a1? 、 a2a_2a2?的關系即a1+Δ1≥a2a_1+\Delta_1 \ge a_2a1?+Δ1?≥a2?
肯定是希望∑Δ\sum \Delta∑Δ 盡可能小,所以Δ\DeltaΔ 取到等號最優,即 Δi=ai+1?ai\Delta_i=a_{i+1}-a_iΔi?=ai+1??ai?
對于bn=b1+∑Δb_n=b_1+\sum \Deltabn?=b1?+∑Δ,而c1c_1c1?我們希望最好和bnb_nbn?接近,分析可知c1c_1c1?和bnb_nbn?是地位相同的即c1c_1c1?和bnb_nbn?可以互推,因而最優解能夠保證存在一組解是他們兩個最接近。
c1=b1+∑Δ?>c1+c1=b1+c1+∑Δ=a1+∑Δc_1=b_1+\sum \Delta->c_1+c_1=b_1+c_1+\sum\Delta=a_1+\sum\Deltac1?=b1?+∑Δ?>c1?+c1?=b1?+c1?+∑Δ=a1?+∑Δ
因此max(bn,c1)=?a1+∑Δ2?max(b_n,c_1)=\left \lceil \frac{a_1+\sum \Delta}{2} \right \rceilmax(bn?,c1?)=?2a1?+∑Δ??即為最終答案。
注意負數上取整和正數不一樣
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std
;
typedef long long ll
;
const int N
=100010;
ll a
[N
],d
[N
];
int n
,q
;
ll
calc(ll x
)
{if(x
>=0) return (x
+1)/2;else return x
/2;
}
int main()
{IO
;int T
=1;while(T
--){ll now
=0;cin
>>n
;for(int i
=1;i
<=n
;i
++){cin
>>a
[i
];d
[i
]=a
[i
]-a
[i
-1];if(i
>1) now
+=max(0ll,d
[i
]);}cout
<<calc(now
+a
[1])<<'\n';cin
>>q
;while(q
--){int l
,r
;ll c
;cin
>>l
>>r
>>c
;if(l
==1) a
[1]+=c
;r
++;if(l
>1){now
-=max(0ll,d
[l
]);d
[l
]+=c
;now
+=max(0ll,d
[l
]);}if(r
<=n
){now
-=max(0ll,d
[r
]);d
[r
]-=c
;now
+=max(0ll,d
[r
]);}cout
<<calc(now
+a
[1])<<'\n';}}return 0;
}
D題需要認真靜下心來分析,需要多多練習
要加油哦~
總結
以上是生活随笔為你收集整理的Codeforces Round #670 (Div. 2)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。