Educational Codeforces Round

B. String LCM
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Let’s define a multiplication operation between a string a and a positive integer x: a⋅x is the string that is a result of writing x copies of a one after another. For example, “abc” ⋅ 2 = “abcabc”, “a” ⋅ 5 = “aaaaa”.

A string a is divisible by another string b if there exists an integer x such that b⋅x=a. For example, “abababab” is divisible by “ab”, but is not divisible by “ababab” or “aa”.

LCM of two strings s and t (defined as LCM(s,t)) is the shortest non-empty string that is divisible by both s and t.

You are given two strings s and t. Find LCM(s,t) or report that it does not exist. It can be shown that if LCM(s,t) exists, it is unique.

Input
The first line contains one integer q (1≤q≤2000) — the number of test cases.

Each test case consists of two lines, containing strings s and t (1≤|s|,|t|≤20). Each character in each of these strings is either ‘a’ or ‘b’.

Output
For each test case, print LCM(s,t) if it exists; otherwise, print -1. It can be shown that if LCM(s,t) exists, it is unique.

Example
inputCopy
3
baba
ba
aa
aaa
aba
ab
outputCopy
baba
aaaaaa
-1
Note
In the first test case, “baba” = “baba” ⋅ 1 = “ba” ⋅ 2.

In the second test case, “aaaaaa” = “aa” ⋅ 3 = “aaa” ⋅ 2.

找到他们的最小公倍数然后看他们分别构成的那个字符串是否相等

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h> 
 
using namespace std;
 
#define gt(x) x = read()
#define int long long
#define Ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0);
 
const int mod = 1e9 + 7;
 
inline int read(int out = 0)
{
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}
 
const int N = 11000;
const int M = 1e6 + 10;
 
signed main(){
//	freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
//	Ios
	
	int T;
	gt(T);
	
	while(T --){
		string str1, str2;
		cin >> str1 >> str2;
		int mind = min(str1.size(), str2.size());
		int cnt = 1;
		for (int i = 1; ; i ++){
			if (i * mind % str1.size() == 0 && i * mind % str2.size() == 0){
				cnt = i;
				break;
			}
		}
		
		string str3;
		for (int i = 1; i <= cnt; i ++){
			if (str1.size() < str2.size())   str3 += str1;
			else   str3 += str2;
		}
		
		string str4, str5;
		for (int i = 1; i <= (str3.size() / str1.size()); i ++){
			str4 += str1;
		}   
		
		for (int i = 1; i <= (str3.size() / str2.size()); i ++){
			str5 += str2;
		} 
		
		if (str4 != str5)     cout << "-1" << endl;
		else  cout << str3  << endl;  
	}
    
	return 0;
}

C. No More Inversions
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You have a sequence a with n elements 1,2,3,…,k−1,k,k−1,k−2,…,k−(n−k) (k≤n<2k).

Let’s call as inversion in a a pair of indices i<j such that a[i]>a[j].

Suppose, you have some permutation p of size k and you build a sequence b of size n in the following manner: b[i]=p[a[i]].

Your goal is to find such permutation p that the total number of inversions in b doesn’t exceed the total number of inversions in a, and b is lexicographically maximum.

Small reminder: the sequence of k integers is called a permutation if it contains all integers from 1 to k exactly once.

Another small reminder: a sequence s is lexicographically smaller than another sequence t, if either s is a prefix of t, or for the first i such that si≠ti, si<ti holds (in the first position that these sequences are different, s has smaller number than t).

Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.

The first and only line of each test case contains two integers n and k (k≤n<2k; 1≤k≤105) — the length of the sequence a and its maximum.

It’s guaranteed that the total sum of k over test cases doesn’t exceed 105.

Output
For each test case, print k integers — the permutation p which maximizes b lexicographically without increasing the total number of inversions.

It can be proven that p exists and is unique.

Example
inputCopy
4
1 1
2 2
3 2
4 3
outputCopy
1
1 2
2 1
1 3 2
Note
In the first test case, the sequence a=[1], there is only one permutation p=[1].

In the second test case, the sequence a=[1,2]. There is no inversion in a, so there is only one permutation p=[1,2] which doesn’t increase the number of inversions.

In the third test case, a=[1,2,1] and has 1 inversion. If we use p=[2,1], then b=[p[a[1]],p[a[2]],p[a[3]]]=[2,1,2] and also has 1 inversion.

In the fourth test case, a=[1,2,3,2], and since p=[1,3,2] then b=[1,3,2,3]. Both a and b have 1 inversion and b is the lexicographically maximum.

a数组中的逆序对就是 k ,之后的数。如[1,2,3,4,3,2],就是[4,3,2],这一部分。生成的b数组的后半部分(左右对称的部分)就是[p[2],p[3],p[4],p[3],p[2]],可以发现,如果p数组就是有序的,那么生成的就是 23432,逆序对数量一定是等于a数组的,因为其实就是b数组等于a数组了,一模一样,但是,如果p中这部分值是逆序的,那么生成的就是 43234,逆序对数量也等于a数组!!。那么显然逆序排列是字典序最大的。所以答案就是这个东西了!前面不对称的部分不能改,改了逆序对就比a数组更多。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h> 
 
using namespace std;
 
#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
 
const int mod = 1e9 + 7;
 
inline int read(int out = 0)
{
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}
 
const int N = 11000;
const int M = 1e6 + 10;
 
signed main(){
//	freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
	ios;
	
	int T;
	gt(T);
	
    while(T --){
    	int n, k;
    	gt(n), gt(k);
    	int res = (n - k);
    	int temp = (k - res - 1);
    	
    	for (int i = 1; i <= temp; i ++)   cout << i << " ";
    	for (int i = k; i > temp; i --)    cout << i << " ";
    	cout << endl;
	}
	return 0;
}

D. Program
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a program that consists of n instructions. Initially a single variable x is assigned to 0. Afterwards, the instructions are of two types:

increase x by 1;
decrease x by 1.
You are given m queries of the following format:

query l r — how many distinct values is x assigned to if all the instructions between the l-th one and the r-th one inclusive are ignored and the rest are executed without changing the order?
Input
The first line contains a single integer t (1≤t≤1000) — the number of testcases.

Then the description of t testcases follows.

The first line of each testcase contains two integers n and m (1≤n,m≤2⋅105) — the number of instructions in the program and the number of queries.

The second line of each testcase contains a program — a string of n characters: each character is either ‘+’ or ‘-’ — increment and decrement instruction, respectively.

Each of the next m lines contains two integers l and r (1≤l≤r≤n) — the description of the query.

The sum of n over all testcases doesn’t exceed 2⋅105. The sum of m over all testcases doesn’t exceed 2⋅105.

Output
For each testcase print m integers — for each query l, r print the number of distinct values variable x is assigned to if all the instructions between the l-th one and the r-th one inclusive are ignored and the rest are executed without changing the order.

Example
inputCopy
2
8 4
-±-±-+
1 8
2 8
2 5
1 1
4 10
±++
1 1
1 2
2 2
1 3
2 3
3 3
1 4
2 4
3 4
4 4
outputCopy
1
2
4
4
3
3
4
2
3
2
1
2
2
2
Note
The instructions that remain for each query of the first testcase are:

empty program — x was only equal to 0;
“-” — x had values 0 and −1;
“—+” — x had values 0, −1, −2, −3, −2 — there are 4 distinct values among them;
“±-±-+” — the distinct values are 1, 0, −1, −2.

处理一个前面符号处理后的可以得到的最大的数和最小的数分别是多少,在处理出每个数的时候是多少,再向后处理出每个位置向后走最大能加多少,最小能加多少,查询的时候就可以知道这一段数在加减的过程中最大的数和最小的数分别是多少了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <queue>
#include <map>
#include <stack>
#include <map>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <ext/rope>
#include <bits/stdc++.h> 

using namespace std;

#define gt(x) x = read()
#define int long long
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

const int mod = 1e9 + 7;

inline int read(int out = 0)
{
    char c;
    while((c=getchar()) < 48 || c > 57);
    while(c >= 48 && c <= 57) out=out*10+c-48,c=getchar();
    return out; 
}

const int N = 2e5 + 10;
const int M = 1e6 + 10;

int h[N], a[N], b[N], c[N], d[N];

//倒序循环,倒序后缀和 
//对字符串有处理下标从1开始,读入char 
signed main(){
//	freopen("C:\\Users\\wwb0719\\Desktop\\stdin.txt", "r", stdin);
	ios;
	
	int T;
	scanf("%lld",&T);
	while(T--){
		int n, m;
		char s[N];
		scanf("%lld%lld",&n,&m);
		scanf("%s",s+1);
		for(int i=1; i<=n; i++){
			if(s[i]=='+')
				h[i]=h[i-1]+1;
			else
				h[i]=h[i-1]-1;
			a[i]=max(a[i-1],h[i]);
			b[i]=min(b[i-1],h[i]);
		}
		c[n+1]=0,d[n+1]=0;
		for(int i=n; i>=1; i--){
			int v=s[i]=='+'?1:-1;
			c[i]=max(0ll,c[i+1]+v);
			d[i]=min(0ll,d[i+1]+v);
		}
		for(int i=1; i<=m; i++){
			int l,r,A,B;
			scanf("%d%d",&l,&r);
			A=max(a[l-1],h[l-1]+c[r+1]);
			B=min(b[l-1],h[l-1]+d[r+1]);
			printf("%lld\n",A-B+1);
		}
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值