Codeforces Round #572 (Div. 2)简要题解
作者:互联网
A. Keanu Reeves
分析:01个数相等答案就是1,不相等就是2。
#include "bits/stdc++.h"
using namespace std;
int main(){
int n;
string s;
cin>>n>>s;
int z=0,o=0;
for (int i = 0; i < n; ++i) {
if(s[i]=='1')o++;
else z++;
}
if(z!=o){
puts("1");
cout<<s<<endl;
}
else {
puts("2");
cout<<s[0]<<endl;
for (int i = 1; i < n; ++i) {
cout<<s[i];
}
}
}
B. Number Circle
分析:排序之后分奇偶放左右,注意特判一下不可能的情况就可以了,证明不写了。
#include "bits/stdc++.h"
using namespace std;
int a[100004];
int main(){
int n;
cin>>n;
for (int i = 0; i < n; ++i) {
scanf("%d",&a[i]);
}
sort(a,a+n);
if(a[n-1]>=a[n-2]+a[n-3])puts("NO");
else {
deque<int>q;
puts("YES");
for (int i = 0; i < n; ++i) {
if(i&1)q.push_back(a[i]);
else q.push_front(a[i]);
}
while (!q.empty()){
printf("%d ",q.front());
q.pop_front();
}
}
}
C. Candies!
分析:合并操作是相加取模,且所有数<=9,那么答案就是区间合/10。
#include "bits/stdc++.h"
using namespace std;
int a[100004];
int pre[100004];
int main() {
int n;
cin >> n;
pre[0]=0;
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
pre[i]=pre[i-1]+a[i];
}
int q;
cin >> q;
for (int i = 0; i < q; ++i) {
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n",(pre[r]-pre[l-1])/10);
}
}
D1. Add on a Tree
分析:判断一下是否存在度为2的点就可以了。
#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int num[100004];
int main(){
int n;
cin>>n;
for (int i = 0; i < n-1; ++i) {
int u,v;
scanf("%d%d",&u,&v);
num[u]++;
num[v]++;
}
for (int i = 1; i <= n; ++i) {
if(num[i]==2){
puts("NO");
return 0;
}
}
puts("YES");
}
D2. Add on a Tree: Revolution
分析:要将某条边置0且不改变其他边的状态,对于这条边的两个点,分别找出两个叶子节点(如果有的话)x,y,a,b,,然后add(x,a,w/2),add(y,b,w/2),add(x,y,-w/2),add(a,b,-w/2),特判一下这个点本来就是叶子节点的情况就可以了。数据量很小,怎么写都能过。
#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9 + 7;
struct node{
int u,w;
};
bool vis[1004];
vector<node>v[1004];
int ans[1004][1004];
int Find(int u,int pre){
vis[u]=1;
if(v[u].size()==1)return u;
for (int i = 0; i < v[u].size(); ++i) {
if(v[u][i].u==pre)continue;
if(vis[v[u][i].u])continue;
return Find(v[u][i].u,u);
}
}
void dfs(int u,int pre,int w){
if(w!=0){
if(v[u].size()!=1 && v[pre].size()!=1){
memset(vis,0, sizeof(vis));
int x = Find(u,pre);
int y = Find(u,pre);
int a = Find(pre,u);
int b = Find(pre,u);
ans[x][a]+=w/2;
ans[y][b]+=w/2;
ans[x][y]-=w/2;
ans[a][b]-=w/2;
ans[a][x]+=w/2;
ans[b][y]+=w/2;
ans[y][x]-=w/2;
ans[b][a]-=w/2;
}
else if(v[u].size()!=1 && v[pre].size()==1){
memset(vis,0, sizeof(vis));
int x = Find(u,pre);
int y = Find(u,pre);
ans[pre][x]+=w/2;
ans[pre][y]+=w/2;
ans[y][x]-=w/2;
ans[x][pre]+=w/2;
ans[y][pre]+=w/2;
ans[x][y]-=w/2;
}
else if(v[u].size()==1 && v[pre].size()!=1){
memset(vis,0, sizeof(vis));
int a = Find(pre,u);
int b = Find(pre,u);
ans[u][a]+=w/2;
ans[u][b]+=w/2;
ans[b][a]-=w/2;
ans[a][u]+=w/2;
ans[b][u]+=w/2;
ans[a][b]-=w/2;
}
else if(v[u].size()==1 && v[pre].size()==1){
memset(vis,0, sizeof(vis));
ans[u][pre]+=w/2;
ans[pre][u]+=w/2;
}
}
for (int i = 0; i < v[u].size(); ++i) {
if(v[u][i].u!=pre)dfs(v[u][i].u,u,v[u][i].w);
}
}
int main() {
int n;
cin>>n;
int x,y,z;
memset(ans,0, sizeof(ans));
for (int i = 0; i < n-1; ++i) {
scanf("%d%d%d",&x,&y,&z);
v[x].push_back({y,z});
v[y].push_back({x,z});
}
for (int i = 1; i <= n; ++i) {
if(v[i].size()==2){
puts("NO");
return 0;
}
}
puts("YES");
dfs(1,-1,0);
int cnt = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < i; ++j) {
if(ans[i][j]!=0){
cnt++;
}
}
}
cout<<cnt<<endl;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < i; ++j) {
if(ans[i][j]!=0){
printf("%d %d %d\n",i,j,ans[i][j]);
}
}
}
}
E. Count Pairs
分析:化简:
即变成求
然后就可以线性处理了。
#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9 + 7;
unordered_map<long long, int> mp;
int main() {
int n, p, k;
cin >> n >> p >> k;
long long ans = 0;
long long x;
for (int i = 0; i < n; ++i) {
scanf("%lld", &x);
long long res = (x * x % p * x % p * x % p - k * x % p + p) % p;
ans += mp[res]++;
}
cout << ans << endl;
}
F. Array Beauty
分析:设f(x)为beauty>=x的长度为k的子序列。
容易得到,即beauty为x的被计算x次。同时,由于a[i]最大只有1e5,那么数组的最大beauty应该为1e5/(k-1),证明略。
对于每个f[i],用dp[i][j]表示前i个取j个,beauty>=x的种类数,就可以在的时间内求出。
那么总复杂度为
#include "bits/stdc++.h"
using namespace std;
const int mod = 998244353;
int dp[1004][1004],a[1004];
int main(){
int n,k;
cin>>n>>k;
for (int i = 1; i <= n; ++i) {
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
int ans = 0;
for (int m = 1; m <= 100000/(k-1); ++m) {
dp[0][0]=1;
int pos = 0;
for (int i = 1; i <= n; ++i) {
while (pos < i && a[i] - a[pos+1] >= m)pos++;
dp[i][0]=1;
for (int j = 1; j <= k; ++j) {
dp[i][j] = (dp[i-1][j] + dp[pos][j-1])%mod;
}
}
ans = (ans + dp[n][k])%mod;
}
cout<<ans;
}
标签:pre,std,vis,int,题解,Codeforces,++,ans,572 来源: https://blog.csdn.net/qq_42671946/article/details/95867445