Codeforces Global Round 7

A. Bad Ugly Numbers

You are given a integer n (n>0). Find any integer s which satisfies these conditions, or report that there are no such numbers:
In the decimal representation of s:
s>0,
s consists of n digits,
no digit in s equals 0,
s is not divisible by any of it's digits.
Input
The input consists of multiple test cases. The first line of the input contains a single integer t (1≤t≤400), the number of test cases. The next t lines each describe a test case.
Each test case contains one positive integer n (1≤n≤105).
It is guaranteed that the sum of n for all test cases does not exceed 105.
Output
For each test case, print an integer s which satisfies the conditions described above, or "-1" (without quotes), if no such number exists. If there are multiple possible solutions for s, print any solution.
Example
input
4
1
2
3
4
output
-1
57
239
6789
Note
In the first test case, there are no possible solutions for s consisting of one digit, because any such solution is divisible by itself.
For the second test case, the possible solutions are: 23, 27, 29, 34, 37, 38, 43, 46, 47, 49, 53, 54, 56, 57, 58, 59, 67, 68, 69, 73, 74, 76, 78, 79, 83, 86, 87, 89, 94, 97, and 98.
For the third test case, one possible solution is 239 because 239 is not divisible by 2, 3 or 9 and has three digits (none of which equals zero).

思路: 瞎猜发现了一个很有意思的数列:23,233,2333,23333...

#include<iostream>
using namespace std;
int main(){
    int T,n;
    cin>>T;
    while(T--){
        cin>>n;
        if(n==1){
            puts("-1");
        }
        else {
            cout<<2;
            for(int i=1;i<n;++i){
                cout<<3;
            }
            cout<<endl;
        }
    }
    return 0;
}

B. Maximums

Alicia has an array, a1,a2,…,an, of non-negative integers. For each 1≤i≤n, she has found a non-negative integer xi=max(0,a1,…,ai−1). Note that for i=1, xi=0.
For example, if Alicia had the array a={0,1,2,0,3}, then x={0,0,1,2,2}.
Then, she calculated an array, b1,b2,…,bn: bi=ai−xi.
For example, if Alicia had the array a={0,1,2,0,3}, b={0−0,1−0,2−1,0−2,3−2}={0,1,1,−2,1}.
Alicia gives you the values b1,b2,…,bn and asks you to restore the values a1,a2,…,an. Can you help her solve the problem?
Input
The first line contains one integer n (3≤n≤200000) – the number of elements in Alicia's array.
The next line contains n integers, b1,b2,…,bn (−109≤bi≤109).
It is guaranteed that for the given array b there is a solution a1,a2,…,an, for all elements of which the following is true: 0≤ai≤109.
Output
Print n integers, a1,a2,…,an (0≤ai≤109), such that if you calculate x according to the statement, b1 will be equal to a1−x1, b2 will be equal to a2−x2, ..., and bn will be equal to an−xn.
It is guaranteed that there exists at least one solution for the given tests. It can be shown that the solution is unique.
Examples
input
5
0 1 1 -2 1
output
0 1 2 0 3
input
3
1000 999999000 -1000000000
output
1000 1000000000 0
input
5
2 1 2 2 3
outputCopy
2 3 5 7 10
Note
The first test was described in the problem statement.
In the second test, if Alicia had an array a={1000,1000000000,0}, then x={0,1000,1000000000} and b={1000−0,1000000000−1000,0−1000000000}={1000,999999000,−1000000000}.

思路: 可以转化为bi等于ai减去a:1i-1个数的最大值,那么ai就等于bi加上a:1i-1个数的最大值

#include<iostream>
#include<string.h>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
#include<set>
#include<map>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
const int N=200010;
LL b[N],a[N],Max;
int main(){
    int n;
    cin>>n;
    Max=0;
    for(int i=1;i<=n;++i){
        cin>>b[i];
        a[i]=b[i]+Max;
        Max=max(Max,a[i]);
    }
    for(int i=1;i<=n;++i){
        cout<<a[i]<<" ";
    }
    return 0;
}

C. Permutation Partitions

You are given a permutation p1,p2,…,pn of integers from 1 to n and an integer k, such that 1≤k≤n. A permutation means that every number from 1 to n is contained in p exactly once.
Let's consider all partitions of this permutation into k disjoint segments. Formally, a partition is a set of segments {[l1,r1],[l2,r2],…,[lk,rk]}, such that:
1≤li≤ri≤n for all 1≤i≤k;
For all 1≤j≤n there exists exactly one segment [li,ri], such that li≤j≤ri.
Two partitions are different if there exists a segment that lies in one partition but not the other.
Let's calculate the partition value, defined as ∑i=1kmaxli≤j≤ripj, for all possible partitions of the permutation into k disjoint segments. Find the maximum possible partition value over all such partitions, and the number of partitions with this value. As the second value can be very large, you should find its remainder when divided by 998244353.
Input
The first line contains two integers, n and k (1≤k≤n≤200000) — the size of the given permutation and the number of segments in a partition.
The second line contains n different integers p1,p2,…,pn (1≤pi≤n) — the given permutation.
Output
Print two integers — the maximum possible partition value over all partitions of the permutation into k disjoint segments and the number of such partitions for which the partition value is equal to the maximum possible value, modulo 998244353.
Please note that you should only find the second value modulo 998244353.
Examples
input
3 2
2 1 3
output
5 2
input
5 5
2 1 5 3 4
output
15 1
input
7 3
2 7 3 1 5 4 6
output
18 6
Note
In the first test, for k=2, there exists only two valid partitions: {[1,1],[2,3]} and {[1,2],[3,3]}. For each partition, the partition value is equal to 2+3=5. So, the maximum possible value is 5 and the number of partitions is 2.
In the third test, for k=3, the partitions with the maximum possible partition value are {[1,2],[3,5],[6,7]}, {[1,3],[4,5],[6,7]}, {[1,4],[5,5],[6,7]}, {[1,2],[3,6],[7,7]}, {[1,3],[4,6],[7,7]}, {[1,4],[5,6],[7,7]}. For all of them, the partition value is equal to 7+5+6=18.
The partition {[1,2],[3,4],[5,7]}, however, has the partition value 7+3+6=16. This is not the maximum possible value, so we don't count it.

思路: 将长度为n的1~n数列划分K段,求合适的划分下每一段的最大值之和的最大值是多少,并求有多少种划分可以满足。最大就要将最大的K个数单独分到一段,再考虑每一段的端点的可能。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod=998244353;
int main(){
    LL n,k,len=0,ans1,ans2=0;
    cin>>n>>k;
    ans1=(2*n-k+1)*k/2;
    for(int i=1;i<=n;++i){
        LL x;
        cin>>x;
        if(n-k+1<=x) {
            if(ans2==0) ans2=1,len=0  ;
            else {
                ans2=ans2*(len+1)%mod;
                len=0;
            }
        }
        else len++,len%=mod;
    }
    cout<<ans1<<" "<<ans2<<endl;
    return 0;
}

D1. Prefix-Suffix Palindrome (Easy version)   D2. Prefix-Suffix >Palindrome (Hard version)

This is the hard version of the problem. The difference is the constraint on the sum of lengths of strings and the number of test cases. You can make hacks only if you solve all versions of this task.
You are given a string s, consisting of lowercase English letters. Find the longest string, t, which satisfies the following conditions:
The length of t does not exceed the length of s.
t is a palindrome.
There exists two strings a and b (possibly empty), such that t=a+b ( "+" represents concatenation), and a is prefix of s while b is suffix of s.
Input
The input consists of multiple test cases. The first line contains a single integer t (1≤t≤105), the number of test cases. The next t lines each describe a test case.
Each test case is a non-empty string s, consisting of lowercase English letters.
It is guaranteed that the sum of lengths of strings over all test cases does not exceed 106.
Output
For each test case, print the longest string which satisfies the conditions described above. If there exists multiple possible solutions, print any of them.
Example
inputCopy
5
a
abcdfdcecba
abbaxyzyx
codeforces
acbba
outputCopy
a
abcdfdcba
xyzyx
c
abba
Note
In the first test, the string s="a" satisfies all conditions.
In the second test, the string "abcdfdcba" satisfies all conditions, because:
Its length is 9, which does not exceed the length of the string s, which equals 11.
It is a palindrome.
"abcdfdcba" = "abcdfdc" + "ba", and "abcdfdc" is a prefix of s while "ba" is a suffix of s.
It can be proven that there does not exist a longer string which satisfies the conditions.
In the fourth test, the string "c" is correct, because "c" = "c" + "" and a or b can be empty. The other possible solution for this test is "s".

思路: 取字符串的前后缀,拼接成最长回文串的长度。
1.尽量取最长的前后缀组成回文串的前后缀。
2.当出现s[i]!=s[j],再考虑最长的从i开头的回文串和以j结尾的回文串
最后答案就是s[0]~s[i-1] + ( s[i]~s[i+lmax-1] / s[r-rmax+1]~s[r] ) + s[r+1]~s[n-1]
马拉车算法的Len数组记录的是再构造串中i为回文中心的一侧的长度加上本身的点,len[i]-1也对应了以原串的回文长度,所以可以算出i开头的回文串和以j结尾的回文串的长度。

#include<bits/stdc++.h>
using namespace std;
int Len[2000005];
char str[2000010],s[1000005];
int len,lmax,rmax;
void init(int l,int r){
    int k=0;
    str[k++] = '$';
    for(int i=l;i<=r;i++){
        str[k++]='#';
        str[k++]=s[i];
    }
    str[k++]='#';
    str[k]=0;
    len=k;
}
void Manacher(){
  Len[0] = 0;
  int sum = 0;
  int mx,id;
  lmax=rmax=mx =id= 0;
  for(int i=1;i<len;i++){
    if(i < mx) Len[i]=min(mx - i, Len[2 * id - i]);
    else Len[i] = 1;
    while(str[i - Len[i]]== str[i + Len[i]]) Len[i]++;
    if(Len[i] + i > mx){
      mx = Len[i] + i;
      id = i;
      sum = max(sum, Len[i]);
    }
    if(i==Len[i]) lmax=max(lmax,Len[i]-1);
    if(Len[i]+i==len) rmax=max(rmax,Len[i]-1);
  }
}
int main(){
    int T;
    cin>>T;
    while(T--){
        cin>>s;
        int lens=strlen(s);
        int l=0,r=lens-1;
        while(l<=r&&s[l]==s[r]) l++,r--;
        if(l>r){
            cout<<s<<endl;
        }
        else {
            init(l,r);
            Manacher();
            if(lmax>rmax){
                for(int i=0;i<l;++i){
                    cout<<s[i];
                }
                for(int i=l;i<l+lmax;++i){
                    cout<<s[i];
                }
                for(int i=r+1;i<lens;++i){
                    cout<<s[i];
                }
            }
            else {
                for(int i=0;i<l;++i){
                    cout<<s[i];
                }
                for(int i=r-rmax+1;i<=r;++i){
                    cout<<s[i];
                }
                for(int i=r+1;i<lens;++i){
                    cout<<s[i];
                }
            }
            cout<<endl;
        }
    }
 
    return 0;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12545816.html