1. 程式人生 > 其它 >Gym 101532 contest (未完)

Gym 101532 contest (未完)

個人總結,如果有錯的地方,歡迎大佬糾正。

A - Subarrays Beauty (二進位制 + 貢獻)

You are given an arrayaconsisting ofnintegers. A subarray(l, r)from arrayais defined as non-empty sequence of consecutive elementsal, al + 1, ..., ar.

The beauty of a subarray(l, r)is calculated as thebitwise ANDfor all elements in the subarray:

Beauty(l, r)=al&al + 1&al + 2&...&ar

Your task is to calculate the summation of the beauty of all subarrays(l, r)(1 ≤ l ≤ r ≤ n):

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test case contains an integern(1 ≤ n ≤ 105), wherenis the size of the arraya

.

The second line of each test case containsnintegersa1, a2, ..., an(1 ≤ ai ≤ 106), giving the arraya.

Output

For each test case, print a single line containing the summation of the beauty of all subarrays in the given array.

Example

Input

2
3
7 11 9
4
11 9 6 11

Output

40
48

Note

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to usescanf/printfinstead ofcin/coutin C++, prefer to useBufferedReader/PrintWriterinstead ofScanner/System.outin Java.

Abitwise ANDtakes two equal-length binary representations and performs the logicalANDoperation on each pair of the corresponding bits, by multiplying them. Thus, if both bits in the compared position are 1, the bit in the resulting binary representation is 1 (1 × 1 = 1); otherwise, the result is 0 (1 × 0 = 0 and 0 × 0 = 0). This operation exists in all modern programming languages, for example in language C++ and Java it is marked as&.

In the first test case, the answer is calculated as summation of 6 subarrays as follow:

Beauty(1, 1) + Beauty(l, 2) + Beauty(1, 3) + Beauty(2, 2) + Beauty(2, 3) + Beauty(3, 3)

(7) + (7&11) + (7&11&9) + (11) + (11&9) + (9) = 40

解題思路:求連續區間的按位與,然後把各個區間的和相加。可以先用陣列把每個數的二進位制儲存,因為是連續區間內,如果二進位制中出現是0, 那麼這個二進位制所在的位置的區間就可以跳過(按位與:只有兩個數是1才是1)。這裡是豎著儲存,例如橫著看是 11101,前面三位都是1,每個1都會貢獻3次, 所以用公式n * (n +1) / 2,可以參考樣例給出的7, 11, 9。當然別忘了左移,如3 二進位制就是11, 最左邊那個1和右邊那個表示的數的大小是不一樣的。

AC程式碼:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

#define ll long long

const int N = 1e5+100;
int a[21][N];

int main(){
	int t;
	scanf("%d", &t);

	while (t --) {
		memset(a,0,sizeof(a));
		int n;
		scanf("%d", &n);
		for (int i = 0; i < n; i ++) {
			int x;
			scanf("%d", &x);
			int cnt = 0;
			while (x) {
				if (x & 1) a[cnt][i] = 1;
				cnt++;
				x >>= 1;
			}
		}
		ll ans = 0;
		for (int i = 0; i < 20; i ++) {
			ll x = 0;
			for (int j = 0; j <= n; j ++) {
				if (a[i][j] == 1) x++;
				else {
					ans += (1ll << i) * (x * (x + 1) / 2);
					x = 0;
				}
			}
		}
		printf("%lld\n", ans);
	}

	return 0;
}

B - Array Reconstructing (暴力)

You are given an arrayaconsisting ofnelementsa1, a2, ..., an. Arrayahas a special property, which is:

ai= (ai - 1+ 1) %m, for eachi(1 < i ≤ n)

You are given the arrayawith some lost elements from it, each lost element is replaced by -1. Your task is to find all the lost elements again, can you?

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test case contains two integersnandm(1 ≤ n ≤ 1000)(1 ≤ m ≤ 109), wherenis the size of the array, andmis the described modulus in the problem statement.

The second line of each test case containsnintegersa1, a2, ..., an( - 1 ≤ ai < m), giving the arraya. If theithelement is lost, thenaiwill be -1. Otherwise,aiwill be a non-negative integer less thanm.

It is guaranteed that the input is correct, and there is at least one non-lost element in the given array.

Output

For each test case, print a single line containingnintegersa1, a2, ..., an, giving the arrayaafter finding all the lost elements.

It is guaranteed that an answer exists for the given input.

Example

Input

4
5 10
1 2 3 4 5
4 10
7 -1 9 -1
6 7
5 -1 -1 1 2 3
6 10
5 -1 7 -1 9 0

Output

1 2 3 4 5
7 8 9 0
5 6 0 1 2 3
5 6 7 8 9 0

Note

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to usescanf/printfinstead ofcin/coutin C++, prefer to useBufferedReader/PrintWriterinstead ofScanner/System.outin Java.

解題思路:這題被坑的有點慘,沒有注意到一個數組中可能只有一個數其他都是需要填的,出現的數可能在中間。只要找到一個不是-1的數直接往前往後推就好了。

AC程式碼:

#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;

#define ll long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int N = 1e7;

int a[N];

int main(){
	int t;
	scanf("%d", &t);
	while (t --) {
		int n, m;
		cin >> n >> m;
		int p = 0;
		for (int i = 1; i <= n; i ++) {
			scanf("%d", &a[i]);
			if (a[i] != -1) p = i;
		}
		for (int i = 1; i <= n; i++) {
			int j = p - 1;
			while (j >= 1) {
				if (a[j] == -1) {
					if (a[j + 1] == 0) a[j] = m - 1;
					else a[j] = a[j + 1] - 1;
				}
				j--;
			}
			j = p + 1;
			while (j <= n) {
				if (a[j] == -1) {
					a[j] = a[j - 1] + 1;
					a[j] %= m;
				}
				j++;
			}
		}
		printf("%d", a[1]);
		for (int i = 2; i <= n; i++) printf(" %d", a[i]);
		printf("\n");

	}

	return 0;
}

c -Large Summation (暴力)

You are given an arrayaconsisting ofnelementa1, a2, ..., an. For each elementaiyou must find another elementaj(i ≠ j), such that the summation ofaiandajmod(109+ 7) (i.e.(ai + aj)% (109+ 7)) is as maximal as possible.

Can you help judges by solving this hard problem?

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test contains an integern(2 ≤ n ≤ 105), wherenis the size of the arraya.

The second line of each test case containsnintegersa1, a2, ..., an(0 ≤ ai < 109 + 7), giving the arraya.

Output

For each test case, print a single line containingnspace separated elements, such that theithelement is the answer to theithelement in the arraya(i.e. the maximum value of(ai + aj)% (109+ 7)).

Example

Input

2
3
1 2 3
2
1000000000 1000000000

Output

4 5 5
999999993 999999993

Note

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to usescanf/printfinstead ofcin/coutin C++, prefer to useBufferedReader/PrintWriterinstead ofScanner/System.outin Java.

解題思路:把給出的陣列排好序,一邊從小到大,一邊從大到小遍歷, 這樣如果小的數加上大的數相加大於1e9+7,那麼往前遍歷,如果發現和前面所有小的數都大於1e9+7,那麼直接加最大的數取餘。因為和最大的數取餘必定大於是最大的,當然還要記錄原來的順序,這種題大致都是先把暴力做法寫出來再優化。

AC程式碼:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

#define ll long long

const int N = 1e5+100;
const int p = 1e9+7;
pair<ll, int>a[N];
ll b[N];

int main(){
	int t;
	scanf("%d", &t);

	while (t --) {
		int n;
		scanf("%d", &n);
		memset(b, -1, sizeof(b));
		for (int i = 0; i < n; i ++) {
			ll x;
			scanf("%lld", &x);
			a[i] = {x, i};
		}
		sort(a, a+n);
		int j = n - 1;
		for (int i = 0; i < n; i ++) {
			for (; j >= 0; j--) {
				if (a[i].first + a[j].first >= p || i == j) continue;
				b[a[i].second] = a[i].first + a[j].first;
				break;
				//b[j] = max(b[j], b[i]);
			}
			if (b[a[i].second] == -1) {
				int t = n - 1;
				if (i == t) t = n - 2;
				b[a[i].second] = (a[i].first + a[t].first) % p;
			}
		}
		printf("%lld", b[0]);
		for (int i = 1; i < n; i ++) printf(" %lld", b[i]);
		printf("\n");
	}

	return 0;
}

D - Counting Test (字首和)

Yousef has a stringsthat is used to build a magical stringwby repeating the stringsinfinitely many times. For example, ifs = aabbb, thenw = aabbbaabbbaabbbaabbb....

Mohammad always claims that his memory is strong, and that his ability to count is very high, so Yousef decided to hold a test for Mohammad, in order to know the truth of his claims.

Yousef will give Mohammadqqueries, such that each query consisting of two integerslandr, and a lowercase English letterc. The answer of each query is how many times the lettercappears between thelthandrthletters instringw.

Mohammad must answer all the queries correctly, in order to proof his claims, but currently he is busy finishing his meal. Can you help Mohammad by answering all queries?

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test case contains two integersnandq(1 ≤ n ≤ 104)(1 ≤ q ≤ 105), wherenis the length of strings, andqis the number of queries.

The second line of each test case contains the stringsof lengthnconsisting only of lowercase English letters.

Thenqlines follow, each line contains two integerslandrand a lowercase English letterc(1 ≤ l ≤ r ≤ 109), giving the queries.

Output

For each query, print a single line containing how many times the lettercappears between thelthandrthletters instringw.

Example

Input

1
8 5
abcabdca
1 8 c
1 15 b
4 9 a
5 25 d
2 7 c

Output

2
4
3
3
2

Note

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to usescanf/printfinstead ofcin/coutin C++, prefer to useBufferedReader/PrintWriterinstead ofScanner/System.outin Java.

解題思路:先用暴力算出每個字母出現次數的字首和,再計算,計算時先求出必定完整的一段,再加上最前和最後兩端。

AC程式碼:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
#define ll long long 
const int N = 1e4+100;
char s[N];
int a[26][N];
//vector<int>a[26];

int main(){
    int t;
    scanf("%d", &t);
    while (t --) {
        int n, m;
        memset(a, 0, sizeof(a));
        //cin >> n >> m >> s + 1;
        scanf("%d %d %s", &n, &m, s+1);
        for (int i = 1; i <= n; i ++) {
            a[s[i] - 'a'][i] = 1;
        }
        for (int i = 0; i < 26; i ++) {
            for (int j = 1; j <= n; j ++) {
                a[i][j] = a[i][j - 1] + a[i][j];
            }
        }
        while (m --) {
            ll l, r, ql, qr;
            char c;
            //cin >> l >> r >> c;
            scanf("%lld %lld", &l, &r);
            getchar();
            scanf("%c", &c);
            ll ans = (r / n * n - (l + n - 1) / n * n) / n * a[c - 'a'][n];
            ans += a[c - 'a'][n] - a[c - 'a'][(l % n == 0? n : l % n) - 1];
            ans += a[c - 'a'][r % n];
            printf("%lld\n", ans);
        }
    }

    return 0;
}

E - Game of Dice (折半搜尋 + 逆元)

It is always fun to play with dice, here is one interesting game:

You are givennfair dice with 6 faces, the faces does not necessarily have values from 1 to 6 written on them. instead, they can have any values from 1 to 100 written on them.

Suppose you threw thendice one after another, let us define the result of the throws as the multiplication of the numbers you get from each dice mod109 + 7.

You task is to find how many different ways you can get the result of the dice throws equal tox.

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test case contains two integersnandx(1 ≤ n ≤ 14)(0 ≤ x < 109 + 7), wherenis the number of the dice andxis the required result from the throws.

Thennlines follow, theithline contains 6 integersfi1, fi2, ..., fi6(1 ≤ fij ≤ 100), giving the values ofithdice's faces.

Output

For each test case, print a single line containing how many different ways you can get the result of the dice throws equal tox

Example

Input

3
3 9
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
5 6
1 2 9 9 9 9
1 2 9 9 9 9
1 3 9 9 9 9
1 3 9 9 9 9
1 6 9 9 9 9
5 999999937
100 1 1 1 1 1
100 1 1 1 1 1
100 1 1 1 1 1
100 1 1 1 1 1
100 1 1 1 1 1

Output

3
5
1

解題:把分成兩段搜尋,兩個數相乘取餘後等於x,知道一個數求另一個數就需要用到逆元。

AC程式碼:

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

#define ll long long
const int N = 15;
const int p = 1e9 + 7;
int a[N][7];
int n, x;
map<ll, int>m;
ll ans;

void dfs(int st, int ed, ll t) {
	if (st == ed) {
		m[t]++;
		return;
	}
	for (int i = 0; i < 6; i++) {
		ll q = t * a[st][i] % p;
		dfs(st + 1, ed, q);
	}
}

ll Find(ll a, ll t) {
	ll ret = 1;
	while (t) {
		if (t & 1) ret = ret * a % p;
		t >>= 1;
		a = a * a % p;
	}
	return ret % p;
}

void dfs2(int st, int ed, ll t) {
	if (st == ed) {
		ll c = Find(t, p - 2);
		ans += m[x * c % p];
		return;
	}
	for (int i = 0; i < 6; i++) {
		ll q = t * a[st][i] % p;
		dfs2(st + 1, ed, q);
	}
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &x);
		m.clear();
		for (int i = 0; i < n; i++)
			for (int j = 0; j < 6; j++)
				scanf("%d", &a[i][j]);
		ans = 0;
		dfs(0, n / 2, 1);
		dfs2(n / 2, n, 1);
		printf("%lld\n", ans);
	}
	return 0;
}

F - Strings and Queries (待補)

You are given a set ofnstrings such that all characters in the strings are 'a', 'b', or 'c'.

Also, you are givenqqueries, such that each query consisting of two stringsaandb. The answer of each query is the index of the string with the most number of palindrome substrings between stringsaandbfrom the given set.

Asubstringof the stringsis a sequencesl,sl + 1,...,srfor some integers(l, r)such that(1 ≤ l ≤ r ≤ n), wherenis the length of the strings.

Apalindromeis a word, phrase, number, or other sequence of characters which reads the same backward as forward, such as "madam" or "racecar".

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test case contains two integersnandq(1 ≤ n ≤ 104)(1 ≤ q ≤ 105), wherenis the number of strings, andqis the number of queries.

Thennlines follow, each line contains a non-empty string with length no more than 30, giving the strings. All characters in the strings are 'a', 'b', or 'c'. It is guaranteed that all strings are unique. The given strings are numbered from 1 ton.

Thenqlines follow, each line contains two stringsaandb, giving the queries. It is guaranteed that stringsaandbexist in the given set of strings.

Output

For each query, print a single line containing the index of the string with the most number of palindrome substrings between the given stringsaandb. If there are more than one answer, print the lowest index.

Example

Input

1
5 5
aaaaa
abaabc
cbbaca
abccba
abca
aaaaa abca
cbbaca abccba
abaabc abccba
abccba abca
abaabc abccba

Output

1
4
2
4
2

Note

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to usescanf/printfinstead ofcin/coutin C++, prefer to useBufferedReader/PrintWriterinstead ofScanner/System.outin Java.

G - Magical Indices

Alaa sometimes feels bored at work, so at such times she starts playing with a beautiful arrayaconsisting ofnintegersa1, a2, ..., an.

Alaa starts counting the number of magical indices in the arraya. An indexxis said to be magical if it satisfying the following rules:

  1. 1 < x < n
  2. ay ≤ ax, for eachy(1 ≤ y < x).
  3. ax ≤ az, for eachz(x < z ≤ n).

Can you help Alaa by counting the number of magical indices in the arraya.

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test case contains an integern(1 ≤ n ≤ 106), wherenis the size of the arraya.

The second line of each test case containsnintegersa1, a2, ..., an(1 ≤ ai ≤ 106), giving the arraya.

Output

For each test case, print a single line containing the number of magical indices in the arraya.

Example

Input

2
8
2 1 3 4 6 5 7 9
6
4 2 7 9 8 10

Output

3
1

Note

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to usescanf/printfinstead ofcin/coutin C++, prefer to useBufferedReader/PrintWriterinstead ofScanner/System.outin Java.

解題思路:找到有多少個數, 在陣列中前面的數都比他大後面的數都比他小,用一個數記錄左邊最大的數,然後開個陣列記錄每個右邊到某個位置為止最小的數(差點超時了)

AC程式碼:

#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

#define ll long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int N = 1e6+10;

int a[N];
int b[N];
int main(){
	int t;
	scanf("%d", &t);
	while (t --) {
		int n;
		scanf("%d", &n);
		for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
		int left = a[1];
		left = a[1];
		int ans = 0;
		b[n] = a[n];
		for (int j = n - 1; j >= 1; j --) {
			b[j] = min(b[j + 1], a[j + 1]);
		}
		for (int i = 2; i <= n - 1; i ++) {
			if (left <= a[i] && a[i] <= b[i]){
				ans ++;
			}
			if (a[i] > left) left = a[i];
		}
		printf("%d\n", ans);
	}

	return 0;
}

H - Magical Indices

Husam has a lot of free time, so he is using this time in repairing corrupted binary images.

A Binary image can be represented as 2-dimensional array consisting ofnrows, each of which is divided intomcolumns. The rows are numbered from 1 tonfrom top to bottom, and the columns are numbered from 1 tomfrom left to right. Each cell is identified by a pair (x,y), which means that the cell is located at rowxand columny. The possible values in the binary images are either zero or one.

A binary image is good if all cells in the first row, last row, first column, and last column are ones. Otherwise, the binary image is corrupted. If the binary image is corrupted, Husam will fix it.

Husam wants to fix the image with the minimum number of moves, such that in each move he can swap the values at two different cells.

Can you help Husam by calculating the minimum number of required moves to fix the image?

Input

The first line contains an integerT, whereTis the number of test cases.

The first line of each test case contains two integersnandm(3 ≤ n, m ≤ 50), wherenis the number of rows in the binary image, andmis the number of columns in each row.

Thennlines follow, each line containsmcharacters, giving the binary image. All values in the binary image are either zero or one.

Output

For each test case, print a single line containing -1 if Husam cannot fix the binary image. Otherwise, print the minimum number of required moves to fix the image.

Example

Input

3
3 3
111
101
111
4 4
1111
0111
1000
1111
4 5
10101
01010
10101
01010

Output

0
2
-1

Note

In the first test case, the image is good. In the second test case, Husam needs to swap the values of cells (2, 1) and (2, 2), and swap the values of cells (2, 3) and (3, 4), in order to fix the image.

解題思路:主要注意是矩形不是正方形(哭),只有數字1的個數大於等於邊長就數邊上有多少個0,否則輸出-1.

AC程式碼:

#include <iostream>
#include <map>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

#define ll long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int N = 1e5+10;
const int p = 1e9+7;
int a[N];
int main(){
	//IOS
	int t;
	cin >> t;
	while (t --) {
		int n, m;
		cin >> n >> m;
		string s;
		ll num = 0;
		ll ans = 0;
		ll r = 0;
		for (int i= 0; i < n; i++) {
			s = "";
			cin >> s;
			for (int j = 0; j < m; j ++) {
				if (s[j] == '1') {
					num ++;
					//if (0 < i && i < n - 1 && 0 < j && j < m - 1) ans ++;
					if (i == 0 || i == n - 1 || j == 0 || j == m - 1) r++;
				} 
			}
		}
		if (num < (n * 2 + m * 2 - 4)) //cout << "-1\n";
			cout <<"-1\n";
		else{ 
			ans = n * 2 + m * 2 - r - 4;
			cout << ans << '\n';
		}
	}

	return 0;
}