Codeforces Round #245 (Div. 1) ABCDE

2023-12-26 08:18
文章标签 codeforces round div 245 abcde

本文主要是介绍Codeforces Round #245 (Div. 1) ABCDE,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

赛前随便选了一场 CF Div 1



A. Xor-tree
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Iahub is very proud of his recent discovery, propagating trees. Right now, he invented a new tree, called xor-tree. After this new revolutionary discovery, he invented a game for kids which uses xor-trees.

The game is played on a tree having n nodes, numbered from 1 to n. Each node i has an initial value initi, which is either 0 or 1. The root of the tree is node 1.

One can perform several (possibly, zero) operations on the tree during the game. The only available type of operation is to pick a node x. Right after someone has picked node x, the value of node x flips, the values of sons of x remain the same, the values of sons of sons of x flips, the values of sons of sons of sons of x remain the same and so on.

The goal of the game is to get each node i to have value goali, which can also be only 0 or 1. You need to reach the goal of the game by using minimum number of operations.

Input

The first line contains an integer n (1 ≤ n ≤ 105). Each of the next n - 1 lines contains two integers ui and vi (1 ≤ ui, vi ≤ nui ≠ vi) meaning there is an edge between nodes ui and vi.

The next line contains n integer numbers, the i-th of them corresponds to initi (initi is either 0 or 1). The following line also contains n integer numbers, the i-th number corresponds to goali (goali is either 0 or 1).

Output

In the first line output an integer number cnt, representing the minimal number of operations you perform. Each of the next cnt lines should contain an integer xi, representing that you pick a node xi.

Examples
input
10
2 1
3 1
4 2
5 1
6 2
7 5
8 6
9 8
10 5
1 0 1 1 0 1 0 1 0 1
1 0 1 0 0 1 1 1 0 1
output
2
4
7



一棵树,每个点上可以是0或者1.对某个点的一次操作可以使自己,自己孙子,自己孙子的孙子....的权值翻转,求最少翻转多少次和翻转的点编号。


dfs,贪心地尽量翻转深度小的点即可。


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=100005,inf=0x3f3f3f3f;  
const ll llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);
int head[maxn],a[maxn],b[maxn];
bool visit[maxn];
int num,ans;
vector<int> v;struct Edge {int from, to, pre;
};
Edge edge[maxn*2];void addedge(int from, int to) {edge[num] = (Edge) {from, to, head[from]};head[from] = num++;edge[num] = (Edge) {to, from, head[to]};head[to] = num++;
}void dfs(int now,int s1,int s2) {visit[now]=1;int flag=0;if (a[now]^s2!=b[now]) ans++,flag=1,v.push_back(now);for (int i=head[now];i!=-1;i=edge[i].pre) {int to=edge[i].to;if (!visit[to])dfs(to,s2^flag,s1);}
}int main() {int n,x,y,i,j;scanf("%d",&n);num=0;memset(head,-1,sizeof(head));for (i=1;i<n;i++) {scanf("%d%d",&x,&y);addedge(x,y);}for (i=1;i<=n;i++) scanf("%d",&a[i]);for (i=1;i<=n;i++) scanf("%d",&b[i]);mem0(visit);ans=0;dfs(1,0,0);printf("%d\n",ans);for (i=0;i<v.size();i++) {printf("%d\n",v[i]);}return 0;
}

B. Working out
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and m columns. Let number a[i][j] represents the calories burned by performing workout at the cell of gym in the i-th line and the j-th column.

Iahub starts with workout located at line 1 and column 1. He needs to finish with workout a[n][m]. After finishing workout a[i][j], he can go to workout a[i + 1][j] or a[i][j + 1]. Similarly, Iahubina starts with workout a[n][1] and she needs to finish with workout a[1][m]. After finishing workout from cell a[i][j], she goes to either a[i][j + 1] or a[i - 1][j].

There is one additional condition for their training. They have to meet in exactly one cell of gym. At that cell, none of them will work out. They will talk about fast exponentiation (pretty odd small talk) and then both of them will move to the next workout.

If a workout was done by either Iahub or Iahubina, it counts as total gain. Please plan a workout for Iahub and Iahubina such as total gain to be as big as possible. Note, that Iahub and Iahubina can perform workouts with different speed, so the number of cells that they use to reach meet cell may differs.

Input

The first line of the input contains two integers n and m (3 ≤ n, m ≤ 1000). Each of the next n lines contains m integers: j-th number from i-th line denotes element a[i][j] (0 ≤ a[i][j] ≤ 105).

Output

The output contains a single number — the maximum total gain possible.

Examples
input
3 3
100 100 100
100 1 100
100 100 100
output
800
Note

Iahub will choose exercises a[1][1] → a[1][2] → a[2][2] → a[3][2] → a[3][3]. Iahubina will choose exercises a[3][1] → a[2][1] → a[2][2] → a[2][3] → a[1][3].




这题有点像经典题传纸条。

一个矩阵,两个人中其中一个从左上到右下,另一个左下到右上。显然两人的路径会相遇一次,相遇格子的价值不计,其余格子的价值计算一次,问两个人所走路径的权值和最大是多少。


DP。先预处理从四个角到某点的最大权值和,再枚举相遇的格子,用四个方向到这个格子的最大权值加起来更新答案。


#include <cstdio>
#include <iostream>
#include <string.h> 
#include <algorithm> 
using namespace std;
typedef long long ll;
const int maxn=1005;
ll dp[5][maxn][maxn];
ll a[maxn][maxn];int main() {int n,m,i,j,k;scanf("%d%d",&n,&m);memset(dp,0,sizeof(dp));for (i=1;i<=n;i++) {for (j=1;j<=m;j++) {scanf("%lld",&a[i][j]);}}dp[1][1][1]=a[1][1];for (i=1;i<=n;i++) {for (j=1;j<=m;j++) {dp[1][i+1][j]=max(dp[1][i+1][j],dp[1][i][j]+a[i+1][j]);dp[1][i][j+1]=max(dp[1][i][j+1],dp[1][i][j]+a[i][j+1]);//	cout << dp[1][i][j] << endl;}}dp[2][1][m]=a[1][m];for (i=1;i<=n;i++) {for (j=m;j>=1;j--) {dp[2][i+1][j]=max(dp[2][i+1][j],dp[2][i][j]+a[i+1][j]);dp[2][i][j-1]=max(dp[2][i][j-1],dp[2][i][j]+a[i][j-1]);}}dp[3][n][1]=a[n][1];for (i=n;i>=1;i--) {for (j=1;j<=m;j++) {dp[3][i-1][j]=max(dp[3][i-1][j],dp[3][i][j]+a[i-1][j]);dp[3][i][j+1]=max(dp[3][i][j+1],dp[3][i][j]+a[i][j+1]);}}dp[4][n][m]=a[n][m];for (i=n;i>=1;i--) {for (j=m;j>=1;j--) {dp[4][i-1][j]=max(dp[4][i-1][j],dp[4][i][j]+a[i-1][j]);dp[4][i][j-1]=max(dp[4][i][j-1],dp[4][i][j]+a[i][j-1]);}}ll ans=0;for (i=2;i<=n-1;i++) {for (j=2;j<=m-1;j++) {ans=max(ans,dp[1][i-1][j]+dp[4][i+1][j]+dp[2][i][j+1]+dp[3][i][j-1]);ans=max(ans,dp[1][i][j-1]+dp[4][i][j+1]+dp[2][i-1][j]+dp[3][i+1][j]);}}printf("%lld\n",ans);return 0;
}

C. Guess the Tree
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Iahub and Iahubina went to a picnic in a forest full of trees. Less than 5 minutes passed before Iahub remembered of trees from programming. Moreover, he invented a new problem and Iahubina has to solve it, otherwise Iahub won't give her the food.

Iahub asks Iahubina: can you build a rooted tree, such that

  • each internal node (a node with at least one son) has at least two sons;
  • node i has ci nodes in its subtree?

Iahubina has to guess the tree. Being a smart girl, she realized that it's possible no tree can follow Iahub's restrictions. In this way, Iahub will eat all the food. You need to help Iahubina: determine if there's at least one tree following Iahub's restrictions. The required tree must contain n nodes.

Input

The first line of the input contains integer n (1 ≤ n ≤ 24). Next line contains n positive integers: the i-th number represents ci (1 ≤ ci ≤ n).

Output

Output on the first line "YES" (without quotes) if there exist at least one tree following Iahub's restrictions, otherwise output "NO" (without quotes).

Examples
input
                
4
1 1 1 4
output
YES
input
                
5
1 1 5 2 1
output
NO




有一棵树,给定每个点及其子树的点的数量,要求构造一棵每个点要么是叶子,要么有两个或以上儿子的树。

dfs+剪枝。
两个重要剪枝:
1.儿子的数量最少有一半(这一点可以通过画图发现),先为儿子多的点配儿子,则选择方式太多,所以应该先给儿子数量少的点配儿子。
2.对于当前搜索到的节点,当每一步选择的两个节点子树数量相同时,那么选择这两个节点具有相同的效果。因为儿子数量很多,所以这一步可以有很好的剪枝效果。

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int inf=0x3f3f3f3f;  
const ll maxn=35,llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);
int a[maxn],b[maxn],son[maxn];
bool f[maxn];
int n,cnt=0;bool dfs(int now,int size,int son) {if (now>n) return true;if (size==a[now]&&son>=2)if (dfs(now+1,1,0)) return true; else return false;int i,last=-1;for (i=now-1;i>=1;i--) {if (size+a[i]<=a[now]&&f[i]==0&&last!=a[i]) {f[i]=1;last=a[i];if (dfs(now,size+a[i],son+1)) return true;f[i]=0;}}return false;
}int main() {int i,cnt=0;scanf("%d",&n);for (i=1;i<=n;i++) {scanf("%d",&a[i]);if (a[i]==1) cnt++;}sort(a+1,a+n+1);mem0(f);if (a[n]!=n||cnt<(n+1)/2) printf("NO"); elseif (dfs(cnt+1,1,0)) printf("YES"); else printf("NO");return 0;
}


D. Tricky Function
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Iahub and Sorin are the best competitive programmers in their town. However, they can't both qualify to an important contest. The selection will be made with the help of a single problem. Blatnatalag, a friend of Iahub, managed to get hold of the problem before the contest. Because he wants to make sure Iahub will be the one qualified, he tells Iahub the following task.

You're given an (1-based) array a with n elements. Let's define function f(i, j) (1 ≤ i, j ≤ n) as (i - j)2 + g(i, j)2. Function g is calculated by the following pseudo-code:

int g(int i, int j) {int sum = 0;for (int k = min(i, j) + 1; k <= max(i, j); k = k + 1)sum = sum + a[k];return sum;
}

Find a value mini ≠ j  f(i, j).

Probably by now Iahub already figured out the solution to this problem. Can you?

Input

The first line of input contains a single integer n (2 ≤ n ≤ 100000). Next line contains n integers a[1]a[2], ..., a[n] ( - 104 ≤ a[i] ≤ 104).

Output

Output a single integer — the value of mini ≠ j  f(i, j).

Examples
input
4
1 0 0 -1
output
1
input
2
1 -1
output
2

给你一个数列,问(i-j)^2+(sum[i]-sum[j])^2的最小值。


把每个(i,sum[i])看做平面的一个点,转化为最近点对问题分治进行求解。


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string> 
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=100005,inf=0x3f3f3f3f;  
const ll llinf=0x3f3f3f3f3f3f3f3f;   
const ld pi=acos(-1.0L);
ll a[maxn];
int tem[maxn];struct Point{int x,y;
};
Point p[maxn];bool cmp(Point a,Point b) {return a.x<b.x || (a.x==b.x&&a.y<b.y);
}bool cmpy(int a,int b) {return p[a].y<p[b].y;
}ll sqr(ll x) {return x*x;
}ll dfs(int l,int r) {if (l==r) return llinf;if (l+1==r) return sqr(p[l].x-p[r].x)+sqr(p[l].y-p[r].y);int mid=(l+r)/2;ll d1=dfs(l,mid),d2=dfs(mid+1,r),ans;ans=min(d1,d2);int i,j,m=0;for (i=l;i<=r;i++) if (sqr(p[i].x-p[mid].x)<=ans) tem[m++]=i;sort(tem,tem+m,cmpy);for (i=0;i<m;i++) for (j=i+1;j<m&&sqr(p[tem[i]].y-p[tem[j]].y)<ans;j++)ans=min(ans,sqr(p[tem[i]].x-p[tem[j]].x)+sqr(p[tem[i]].y-p[tem[j]].y));return ans;
}int main() {int n,i;scanf("%d",&n);ll sum=0;for (i=1;i<=n;i++) {scanf("%I64d",&a[i]);sum+=a[i];p[i].x=i;p[i].y=sum;}
//	sort(p+1,p+n+1,cmp);ll ans=dfs(1,n);printf("%I64d\n",ans);return 0;
}


E. Points and Segments 欧拉回路,很有趣的一道题。

这篇关于Codeforces Round #245 (Div. 1) ABCDE的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538689

相关文章

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja

CSS实现DIV三角形

本文内容收集来自网络 #triangle-up {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;} #triangle-down {width: 0;height: 0;bor

创建一个大的DIV,里面的包含两个DIV是可以自由移动

创建一个大的DIV,里面的包含两个DIV是可以自由移动 <body>         <div style="position: relative; background:#DDF8CF;line-height: 50px"> <div style="text-align: center; width: 100%;padding-top: 0px;"><h3>定&nbsp;位&nbsp;

Codeforces Round 971 (Div. 4) (A~G1)

A、B题太简单,不做解释 C 对于 x y 两个方向,每一个方向至少需要 x / k 向上取整的步数,取最大值。 由于 x 方向先移动,假如 x 方向需要的步数多于 y 方向的步数,那么最后 y 方向的那一步就不需要了,答案减 1 代码 #include <iostream>#include <algorithm>#include <vector>#include <string>

CF#271 (Div. 2) D.(dp)

D. Flowers time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/474/problem/D We s

CF #278 (Div. 2) B.(暴力枚举+推导公式+数学构造)

B. Candy Boxes time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/488/problem/B There