皮皮J坐车
Description
皮皮J每天都会在校门口等小白.有一天它发现:有n个男生,m个女生排成两队,司机每一时刻从两个队伍的最前端抽一个人上车.问总共有多少个上车方案.
由于总的方案数较大,将答案mod 1e9+7
Input
输入数据的第一行有一个整数T,表示有T组测试数据。
每组数据有一行只包含n,m
T <= 200,n,m <= 100000
Output
输出一个整数,表示总的方案数
每组测试数据输出一行。
Sample Input
2
2 1
2 2
Sample Output
3
6
Hint
对于样例2:假设n个人的编号为{a,b},m个人的编号为{c,d}
总的方案为{a,b,c,d},{a,c,b,d},{a,c,d,b}.{c,a,b,d},{c,a,d,b},{c,d,a,b}.
PS:组合数:总共n+m个位置,从中任意取n个位置依次把第一个队列中的人放入.剩下m个位置放法固定:第二队的人从头开始依次放入.
或者打个表发现是 C(m+n,n) .
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
#define Mod 1000000007
ll gcd(ll a, ll b, ll &x, ll &y){
if (b == 0){
x = 1, y = 0;
return a;
}
ll q = gcd(b, a % b ,y ,x);
y -= a / b * x;
return q;
}
ll ni(ll m,ll n) {
ll x = 0, y = 0;
gcd(n, m, x, y);
if(y > 0) return y;
else return n + y;
}
ll C(ll a,ll b){
ll num1 = 1, num2 = 1;
for(int i = a - b + 1; i <= a; i++){
num1 = (num1 * i) %Mod;
}
for(int i = 1;i <= b; i++){
num2 = (num2 * i) %Mod;
}
cout << (num1 * ni(num2, Mod)) %Mod << endl;
}
int main() {
int m, n, T;
cin >> T;
while(T--) {
cin >> m >> n;
C(m + n, n);
}
return 0;
}
皮皮J与中二
Description皮皮J平时很爱说些中二的话,有一天上课皮皮J突然喊到
“爆裂吧,现实!破碎吧,精神!Banishment this world !”
于是皮皮J当场被老师点名提问,问题如下
给出字符串S,找到出现次数最多的子串.若有多解 输出长度最长的.若还有多解,输出字典序最小的.
Input
输入数据的第一行有一个整数T,表示有T组测试数据。
每组数据只有一行,代表字符串S
总的字符串的长度不会超过1e5
Output
输出满足条件的子串
Sample Input
2
cnadna
abababab
Sample Output
na
ab
Hint
例如s=xycabdxyab
子串{x},{y},{a},{b},{xy},{ab}都出现两次
{x,y},{a,b}长度为2 {ab}字典序较小 所以输出ab.
思路:我的思路是后缀数组,求出height数组后,每 两个0之间最小的数代表相同长度,个数代表次数。
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define rep(i, a, n) for(int i = a; i < n; i++)
#define per(i, a, n) for(int i = n - 1; i >= a; i--)
const int maxn = (int)1e5+10;
const int inf = 0x3f3f3f3f;
struct SuffixArray {
char s[maxn];
int sa[maxn], rank[maxn], height[maxn];
int t1[maxn], t2[maxn], c[maxn], n;
void build_sa(int m) {
n = strlen(s) + 1;s[n - 1] = 0;
int *x = t1, *y = t2;
rep(i, 0, m) c[i] = 0;
rep(i, 0, n) c[x[i] = s[i]]++;
rep(i, 1, m) c[i] += c[i-1];
per(i, 0, n) sa[--c[x[i]]] = i;
for(int k = 1; k <= n; k <<= 1) {
int p = 0;
rep(i, n - k, n) y[p++] = i;
rep(i, 0, n) if(sa[i] >= k) y[p++] = sa[i] - k;
rep(i, 0, m) c[i] = 0;
rep(i, 0, n) c[x[y[i]]]++;
rep(i, 1, m) c[i] += c[i - 1];
per(i, 0, n) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1, x[sa[0]] = 0;
rep(i, 1, n)
x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i-1] + k] ? p - 1 : p++;
}
}
void build_height(){
int j, k = 0;
rep(i, 0, n) rank[sa[i]] = i;
rep(i, 0, n) {
if(k) k--;
j = sa[rank[i] - 1];
while(s[i + k] == s[j + k])k++;
height[rank[i]] = k;
}
}
void print(int cnt, int ans,int len) {
if(cnt == 1) {printf("%s\n",s);return;}
rep(i, sa[ans], sa[ans] + len) printf("%c",s[i]);printf("\n");
}
void solve() {
int l = strlen(s);
int tcnt = 1, cnt = 1, tlen = inf, len = inf, ans = 1;
height[l + 1] = 0;
rep(i, 1, l + 2) {
if(height[i] != 0) tcnt++, tlen = min(tlen, height[i]);
else {
if(tcnt > cnt){cnt = tcnt, len = tlen, ans = i - 1;}
if(tcnt == cnt && tlen > len){len = tlen, ans = i - 1;}
tcnt = 1, tlen = inf;
}
}
print(cnt, ans, len);
}
}sa;
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%s", sa.s);
sa.build_sa(128);
sa.build_height();
sa.solve();
}
return 0;
}
皮皮J与本田翼
Time Limit:1000MS Memory Limit:65536K
Total Submit:53 Accepted:12
Description
皮皮J作为本田翼的忠实粉丝,决定送给本田翼一份礼物.
它知道本田翼喜欢:只包含若干个数字0和若干个数字k的正数.
并且这个正数要为n的倍数.皮皮J不想这个数字太大,
所以它要你找到满足以上条件中最小那个数.
Input
输入数据的第一行有一个整数T,表示有T组测试数据。
每组数据只有一行,代表数字n和数字k
T <= 20,1 <= n <= 100000. 1 <= k <= 9
Output
输出满足要求的数
Sample Input
2
5 2
7 4
Sample Output
20
4004
思路:直接bfs爆long long .用同余定理剪枝,一个个存。
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = (int)1e6 + 10;
bool used[maxn];
int check(string m, const int n){
int t = 0;
for(int i = 0; i < (int)m.size(); i++){
t = (m[i] - '0' + t * 10) % n;
}
return t;
}
void bfs(int n, string k) {
fill(used, used + n + 1, false);
queue<string> q;
q.push(k);
while(!q.empty()) {
string m = q.front();
q.pop();
int chAns = check(m, n);
if(chAns == 0){
cout << m << endl;
break;
}
else {
if(used[chAns] == false){
q.push(m + "0");
q.push(m + k);
used[chAns] = true;
}
}
}
}
int main() {
int T, n;
string c;
cin >> T;
while(T--) {
cin >> n >> c;
bfs(n, c);
}
return 0;
}