您的位置:首页 > 其它

Educational Codeforces Round 62 (Rated for Div. 2)

2019-05-30 22:55 881 查看

A. Detective Book
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Ivan recently bought a detective book. The book is so interesting that each page of this book introduces some sort of a mystery, which will be explained later. The i-th page contains some mystery that will be explained on page ai (ai≥i).

Ivan wants to read the whole book. Each day, he reads the first page he didn’t read earlier, and continues to read the following pages one by one, until all the mysteries he read about are explained and clear to him (Ivan stops if there does not exist any page i such that Ivan already has read it, but hasn’t read page ai). After that, he closes the book and continues to read it on the following day from the next page.

How many days will it take to read the whole book?

Input
The first line contains single integer n (1≤n≤104) — the number of pages in the book.

The second line contains n integers a1,a2,…,an (i≤ai≤n), where ai is the number of page which contains the explanation of the mystery on page i.

Output
Print one integer — the number of days it will take to read the whole book.

Example
inputCopy
9
1 3 3 6 7 6 8 8 9
outputCopy
4
Note
Explanation of the example test:

During the first day Ivan will read only the first page. During the second day Ivan will read pages number 2 and 3. During the third day — pages 4-8. During the fourth (and the last) day Ivan will read remaining page number 9.

题意:有一本魔术书,第i页讲述的魔术会在第ai页揭晓,你每天会从第一张未被看过页开始看,当天要把自己看过的魔术的谜底全看完,求需要进行几天能把这本书看完

题解:模拟即可

#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
int a[10005];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int ans=0;
int maxx=1;
for(int i=1;i<=n;i++){
maxx=max(a[i],maxx);
if(maxx==i){
ans++;
}
}
printf("%d\n",ans);
return 0;
}

B. Good String
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You have a string s of length n consisting of only characters > and <. You may do some operations with this string, for each operation you have to choose some character that still remains in the string. If you choose a character >, the character that comes right after it is deleted (if the character you chose was the last one, nothing happens). If you choose a character <, the character that comes right before it is deleted (if the character you chose was the first one, nothing happens).

For example, if we choose character > in string > > < >, the string will become to > > >. And if we choose character < in string > <, the string will become to <.

The string is good if there is a sequence of operations such that after performing it only one character will remain in the string. For example, the strings >, > > are good.

Before applying the operations, you may remove any number of characters from the given string (possibly none, possibly up to n−1, but not the whole string). You need to calculate the minimum number of characters to be deleted from string s so that it becomes good.

Input
The first line contains one integer t (1≤t≤100) – the number of test cases. Each test case is represented by two lines.

The first line of i-th test case contains one integer n (1≤n≤100) – the length of string s.

The second line of i-th test case contains string s, consisting of only characters > and <.

Output
For each test case print one line.

For i-th test case print the minimum number of characters to be deleted from string s so that it becomes good.

Example
inputCopy
3
2
<>
3

<<
1

outputCopy
1
0
0
Note
In the first test case we can delete any character in string <>.

In the second test case we don’t need to delete any characters. The string > < < is good, because we can perform the following sequence of operations: > < < → < < → <.

题意:对于一个<>串,规定对于<,你可以把<左边的字符删掉,对于>,你可以把它右边的字符删掉,而如果一个串经过若干次这样的操作能变成只存在一种字符的串的话,就称这个串为好串,现在给出一个<>串,求事先最少删除多少个字符能使这个串变成好串,比如对于>>>>>答案就是0

题解:分析可知只需要考虑所给串的左端<的个数和右端>的个数即可,结果就是min(num1,num2)。先证明这样做的必要性->如果既不删除左端<也不删除右端>,那么总会遗留下至少一个字符,因为最左端<只能由<删除,而最右端>只能由>删除,所以至少会遗留下一端,所以左端<和右端>不能同时存在,所以删除二者之一是必要的,再证明充分性->只要把左端<删掉,左端第一个就是>,就可以删除后面所有字符,同理把右端>删掉,右端第一个就是<,就可以删除前面所有字符,由于删除二者之一既是充分又是必要的,所以就是最优的.

#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
int a[10005];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
char ch[105];
scanf("%d",&n);
scanf("%s",ch+1);
int sta1=1;
int en1=n;
while(sta1<=n&&ch[sta1]=='<')sta1++;
while(en1>=1&&ch[en1]=='>')en1--;
printf("%d\n",min(n-en1,sta1-1));
}
return 0;
}

C. Playlist
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You have a playlist consisting of n songs. The i-th song is characterized by two numbers ti and bi — its length and beauty respectively. The pleasure of listening to set of songs is equal to the total length of the songs in the set multiplied by the minimum beauty among them. For example, the pleasure of listening to a set of 3 songs having lengths [5,7,4] and beauty values [11,14,6] is equal to (5+7+4)⋅6=96.

You need to choose at most k songs from your playlist, so the pleasure of listening to the set of these songs them is maximum possible.

Input
The first line contains two integers n and k (1≤k≤n≤3⋅105) – the number of songs in the playlist and the maximum number of songs you can choose, respectively.

Each of the next n lines contains two integers ti and bi (1≤ti,bi≤106) — the length and beauty of i-th song.

Output
Print one integer — the maximum pleasure you can get.

Examples
inputCopy
4 3
4 7
15 1
3 6
6 8
outputCopy
78
inputCopy
5 3
12 31
112 4
100 100
13 55
55 50
outputCopy
10000
Note
In the first test case we can choose songs 1,3,4, so the total pleasure is (4+3+6)⋅6=78.

In the second test case we can choose song 3. The total pleasure will be equal to 100⋅100=10000.

题意:有n首曲子,每首曲子有自己的演奏时间ai和可听度bi,最多选择k首曲子,求能带来的最大欢乐值,其中欢乐值的值=演奏曲子的总时间*曲子的最小可听度

题解:按照曲子的最小可听度排序,用优先队列维护所选曲子的最大演奏时间,枚举最小可听度即可

#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
struct pot{
ll v1;
ll v2;
bool operator<(const struct pot& aa)const{
return v1>aa.v1;
}
}p[300005];
ll sum[300005];
bool cmp(struct pot aw,struct pot bw){
return aw.v2<bw.v2;
}
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%lld%lld",&p[i].v1,&p[i].v2);
sort(p+1,p+1+n,cmp);
ll sum=0;
ll ans=0;
priority_queue<struct pot>pq;
for(int i=n;i>=1;i--){
if(pq.size()<k){
sum+=p[i].v1;
pq.push(p[i]);
ans=max(ans,sum*p[i].v2);
}
else{
struct pot b0=pq.top();
pq.pop();
sum-=b0.v1;
ans=max(ans,(sum+p[i].v1)*p[i].v2);
if(b0.v1>p[i].v1){
sum+=b0.v1;
pq.push(b0);
}
else{
sum+=p[i].v1;
pq.push(p[i]);
}
}
}
printf("%lld\n",ans);
return 0;
}

D. Minimum Triangulation
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a regular polygon with n vertices labeled from 1 to n in counter-clockwise order. The triangulation of a given polygon is a set of triangles such that each vertex of each triangle is a vertex of the initial polygon, there is no pair of triangles such that their intersection has non-zero area, and the total area of all triangles is equal to the area of the given polygon. The weight of a triangulation is the sum of weigths of triangles it consists of, where the weight of a triagle is denoted as the product of labels of its vertices.

Calculate the minimum weight among all triangulations of the polygon.

Input
The first line contains single integer n (3≤n≤500) — the number of vertices in the regular polygon.

Output
Print one integer — the minimum weight among all triangulations of the given polygon.

Examples
inputCopy
3
outputCopy
6
inputCopy
4
outputCopy
18
Note
According to Wiki: polygon triangulation is the decomposition of a polygonal area (simple polygon) P into a set of triangles, i. e., finding a set of triangles with pairwise non-intersecting interiors whose union is P.

In the first example the polygon is a triangle, so we don’t need to cut it further, so the answer is 1⋅2⋅3=6.

In the second example the polygon is a rectangle, so it should be divided into two triangles. It’s optimal to cut it using diagonal 1−3 so answer is 1⋅2⋅3+1⋅3⋅4=6+12=18.

题意:n边形可以分解成n-2个三角形,n边形的顶点顺时针标号1…n,分割得到的价值=三角形顶点编号乘积之和,求能得到的最大价值

题解:比较特殊的区间dp,可参照floyd枚举中间点进行dp

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<"["<<#x<<"]"<<"  "<<x<<endl;
ll dp[505][505];
const ll inf=1e17;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(abs(i-j)<=1)dp[i][j]=0;
else dp[i][j]=inf;
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+i*j*k);
}
}
}
printf("%lld\n",dp[1][n]);
return 0;
}

E. Palindrome-less Arrays
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Let’s denote that some array b is bad if it contains a subarray bl,bl+1,…,br of odd length more than 1 (l<r and r−l+1 is odd) such that ∀i∈{0,1,…,r−l} bl+i=br−i.

If an array is not bad, it is good.

Now you are given an array a1,a2,…,an. Some elements are replaced by −1. Calculate the number of good arrays you can obtain by replacing each −1 with some integer from 1 to k.

Since the answer can be large, print it modulo 998244353.

Input
The first line contains two integers n and k (2≤n,k≤2⋅105) — the length of array a and the size of “alphabet”, i. e., the upper bound on the numbers you may use to replace −1.

The second line contains n integers a1,a2,…,an (ai=−1 or 1≤ai≤k) — the array a.

Output
Print one integer — the number of good arrays you can get, modulo 998244353.

Examples
inputCopy
2 3
-1 -1
outputCopy
9
inputCopy
5 2
1 -1 -1 1 2
outputCopy
0
inputCopy
5 3
1 -1 -1 1 2
outputCopy
2
inputCopy
4 200000
-1 -1 12345 -1
outputCopy
735945883

题意:给一个序列,其中一些元素为-1,可以填1~k,要求a[i]!=a[i+2],求可行的方案数

题解:分析之后可转化成染色问题,相邻元素不能染同色,而染色问题可以使用dp解决,dp[len][0]表示两端颜色一样的时候长度为len的-1串可以染色的方案数,dp[len][1]表示两端颜色不同时长度为len的-1串可以染色的方案数,可以把len分成两部分len/2来进行dp。
(1)当len%2=1时,dp[len][0]=dp[len/2][0]dp[len/2][0]+dp[len/2][1]dp[len/2][1](k-1),
dp[len][1]=2dp[len/2][0]*dp[len/2][1]+dp[len/2][1]dp[len/2][1](k-2)

(2)当len%2=0时,dp[len][0]=dp[len-1][1](k-1),dp[len][1]=dp[len-1][0]+dp[len-1][1](k-2)

#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
const ll mod=998244353;
ll ww[200005];
ll dp[200005][2];
ll mypow(ll x,ll y){
ll ak=1;
while(y){
if(y&1)ak=ak*x%mod;
x=x*x%mod;
y/=2;
}
return ak;
}
int main(){
ll n,k;
scanf("%lld%lld",&n,&k);
//  int tot,tot2;
for(int i=1;i<=n;i++){
int w;
scanf("%d",&w);
ww[i]=w;
}
dp[0][1]=1;
dp[0][0]=0;
dp[1][0]=k-1;
dp[1][1]=k-2;
for(int i=2;i<=n;i++){
if(i%2){
dp[i][0]=((dp[i/2][0]*dp[i/2][0])%mod+((k-1)*((dp[i/2][1]*dp[i/2][1])%mod))%mod)%mod;
dp[i][1]=((2ll*dp[i/2][1]*dp[i/2][0])%mod+((k-2)*((dp[i/2][1]*dp[i/2][1])%mod))%mod)%mod;
}
else{
dp[i][0]=((k-1)*dp[i-1][1])%mod;
dp[i][1]=(dp[i-1][0]+dp[i-1][1]*(k-2)%mod)%mod;
}
}
ll ans=1;
ll sum1=0;
ll sta1=1;
ll en1;
while(sta1<=n&&ww[sta1]==-1){
sum1++;
sta1+=2;
}
if(sta1<=n)ans=ans*mypow(k-1,sum1)%mod;
else ans=(ans*mypow(k-1,sum1-1)%mod)*k%mod;
sum1=0;
if(sta1<=n){
if(n%2){
en1=n;
while(en1>=1&&ww[en1]==-1){
sum1++;
en1-=2;
}
ans=ans*mypow(k-1,sum1)%mod;
}
else{
en1=n-1;
while(en1>=1&&ww[en1]==-1){
sum1++;
en1-=2;
}
ans=ans*mypow(k-1,sum1)%mod;
}
}
sum1=0;
sta1=2;
while(sta1<=n&&ww[sta1]==-1){
sum1++;
sta1+=2;
}
if(sta1<=n)ans=ans*mypow(k-1,sum1)%mod;
else ans=(ans*mypow(k-1,sum1-1)%mod)*k%mod;
sum1=0;
if(sta1<=n){
if(n%2){
en1=n-1;
while(en1>=1&&ww[en1]==-1){
sum1++;
en1-=2;
}
ans=ans*mypow(k-1,sum1)%mod;
}
else{
en1=n;
while(en1>=1&&ww[en1]==-1){
sum1++;
en1-=2;
}
ans=ans*mypow(k-1,sum1)%mod;
}
}
sum1=0;
sta1=1;
while(sta1<=n&&ww[sta1]==-1)sta1+=2;
en1=n;
if(n%2==0)en1--;
while(en1>=1&&ww[en1]==-1)en1-=2;
int L=sta1;
for(int i=sta1+2;i<=en1;i+=2){
if(ww[i]==-1){
sum1++;
}
else{
if(ww[i]==ww[L]){
ans=ans*(dp[(i-L)/2-1][0])%mod;
}
else{
ans=ans*dp[(i-L)/2-1][1]%mod;
}
sum1=0;
L=i;
}
}
sum1=0;
sta1=2;
while(sta1<=n&&ww[sta1]==-1)sta1+=2;
en1=n;
if(n%2)en1--;
while(en1>=1&&ww[en1]==-1)en1-=2;
L=sta1;
for(int i=sta1+2;i<=en1;i+=2){
if(ww[i]==-1){
sum1++;
}
else{
if(ww[i]==ww[L]){
ans=ans*(dp[(i-L)/2-1][0])%mod;
}
else{
ans=ans*dp[(i-L)/2-1][1]%mod;
}
sum1=0;
L=i;
}
}
printf("%lld\n",ans);
return 0;
}

F. Extending Set of Points
time limit per test3.5 seconds
memory limit per test1024 megabytes
inputstandard input
outputstandard output
For a given set of two-dimensional points S, let’s denote its extension E(S) as the result of the following algorithm:

Create another set of two-dimensional points R, which is initially equal to S. Then, while there exist four numbers x1, y1, x2 and y2 such that (x1,y1)∈R, (x1,y2)∈R, (x2,y1)∈R and (x2,y2)∉R, add (x2,y2) to R. When it is impossible to find such four integers, let R be the result of the algorithm.

Now for the problem itself. You are given a set of two-dimensional points S, which is initially empty. You have to process two types of queries: add some point to S, or remove some point from it. After each query you have to compute the size of E(S).

Input
The first line contains one integer q (1≤q≤3⋅105) — the number of queries.

Then q lines follow, each containing two integers xi, yi (1≤xi,yi≤3⋅105), denoting i-th query as follows: if (xi,yi)∈S, erase it from S, otherwise insert (xi,yi) into S.

Output
Print q integers. i-th integer should be equal to the size of E(S) after processing first i queries.

Example
inputCopy
7
1 1
1 2
2 1
2 2
1 2
1 3
2 1
outputCopy
1 2 4 4 4 6 3

待补
G. Double Tree
time limit per test10 seconds
memory limit per test1024 megabytes
inputstandard input
outputstandard output
You are given a special undirected graph. It consists of 2n vertices numbered from 1 to 2n. The following properties hold for the graph:

there are exactly 3n−2 edges in the graph: n edges connect vertices having odd numbers with vertices having even numbers, n−1 edges connect vertices having odd numbers with each other, and n−1 edges connect vertices having even numbers with each other;
for each edge (u,v) between a pair of vertices with odd numbers, there exists an edge (u+1,v+1), and vice versa;
for each odd number u∈[1,2n−1], there exists an edge (u,u+1);
the graph is connected; moreover, if we delete all vertices with even numbers from it, and all edges incident to them, the graph will become a tree (the same applies to deleting odd vertices).
So, the graph can be represented as two trees having the same structure, and n edges connecting each vertex of the first tree to the corresponding vertex of the second tree.

Edges of the graph are weighted. The length of some simple path in the graph is the sum of weights of traversed edges.

You are given q queries to this graph; in each query, you are asked to compute the length of the shortest path between some pair of vertices in this graph. Can you answer all of the queries?

Input
The first line of the input contains one integer n (2≤n≤3⋅105).

The second line contains n integers w1,2, w3,4, …, w2n−1,2n (1≤wi,i+1≤1012). These integers describe the weights of the edges connecting odd vertices with even ones.

Then n−1 lines follow. i-th line contains four integers xi, yi, wi,1 and wi,2 (1≤xi,yi≤n, xi≠yi, 1≤wi,j≤1012); it describes two edges: one connecting 2xi−1 with 2yi−1 and having weight wi,1; another connecting 2xi with 2yi and having weight wi,2.

The next line contains one integer q (1≤q≤6⋅105) — the number of queries.

Then q lines follow, i-th line contains two integers ui and vi (1≤ui,vi≤2n, ui≠vi), describing a query “compute the length of the shortest path between vertices ui and vi”.

Output
Print q integers, i-th integer should be equal to the answer to the i-th query.

Example
inputCopy
5
3 6 15 4 8
1 2 5 4
2 3 5 7
1 4 1 5
1 5 2 1
3
1 2
5 6
1 10
outputCopy
3
15
4
Note
The graph in the first test looks like that:

待补

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐