F题 Longest Common Subsequence
思路:通过一个函数公式x->(axx+b*x+c)%p构造s和t数组,问s和t的最长公共子序列有多长。如果x相同的话,那后面的所有存在元素都一定相同,但是x不同的话,也有可能通过%p使得后一个数相同。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e6+5;
ll p,x,a,b,c;
ll s[2000006];
int t,n,m;
unordered_map<ll,ll> mp;
ll qk(ll a,ll b){
ll ans=1;
a%=p;
b%=p;
while(b){
if(b&1) ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
int main(){
scanf("%d",&t);
while(t--){
mp.clear();
scanf("%d%d",&n,&m);
scanf("%lld%lld%lld%lld%lld",&p,&x,&a,&b,&c);
s[0]=x;
for(ll i=1;i<=n;i++){//构造s数组
s[i]=((s[i-1]*a%p*s[i-1]%p+b*s[i-1]%p)%p+c%p)%p;
if(mp[s[i]]==0) mp[s[i]]=i;//记录每个元素出现的最开始的位置
}
ll ans=0;
for(ll i=n+1;i<=m+n;i++){//构造t数组
s[i]=((s[i-1]*a%p*s[i-1]%p+b*s[i-1]%p)%p+c%p)%p;
if(mp[s[i]]<0) break;
if(mp[s[i]]>0) {//找出相同序列最长的序列长度
ans=max(ans,min(n-mp[s[i]]+1,m+n-i+1));
mp[s[i]]=-1;
}
}
printf("%lld\n",ans);
}
return 0;
}
D题 Poker Game
思路:一共有十种类型的牌型,模拟AB拿到牌的可能性,由此判断AB必胜或者平局的情况。
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
typedef unsigned long long ull;
const int N = 2e5 + 10;
const int mod = 1e9 + 7;
unordered_map<char, int> rk;
struct node{
int rank, col;
bool operator<(const node r) const{
return rank > r.rank;
}
} A[10], B[10], C[10], tmp[2][10];
bool mark[10];
int cnt[20];
void init(){
int cnt = 0;
for (auto i : "123456789TJQKA")
rk[i] = ++cnt;
cnt = 0;
for (auto i : "SHCD")
rk[i] = ++cnt;
}
int getrank(int p){
for (int i = 1; i <= 15; i++)
cnt[i] = 0;
for (int i = 1; i <= 5; i++){
cnt[tmp[p][i].rank]++;
if (tmp[p][i].rank == 14)
cnt[1]++;
}
bool flag = 1; //判断同花
for (int i = 2; i <= 5; i++)
if (tmp[p][i].col != tmp[p][i - 1].col)
flag = 0;
bool sh = 0; //判断顺子
for (int i = 14; i >= 5; i--){
bool shun = 1;
for (int j = i; j >= i - 4; j--)
if (cnt[j] == 0)
shun = 0;
if (shun)
sh = 1;
}
if (sh && cnt[1] > 0 && cnt[2] > 0)
for (int i = 1; i <= 5; i++)
tmp[p][i].rank = 5 - i + 1;
if (flag && sh)
return 9; //同花顺
for (int i = 14; i >= 2; i--)
if (cnt[i] == 4){ //炸
for (int j = 1; j <= 4; j++)
tmp[p][j].rank = i;
for (int j = 14; j >= 2; j--)
if (cnt[j] == 1)
tmp[p][5].rank = j;
return 8;
}
for (int i = 14; i >= 2; i--)
if (cnt[i] == 3) //三带二
for (int j = 14; j >= 2; j--)
if (cnt[j] == 2){
for (int k = 1; k <= 3; k++)
tmp[p][k].rank = i;
for (int k = 4; k <= 5; k++)
tmp[p][k].rank = j;
return 7;
}
if (flag)
return 6; //同花
if (sh)
return 5; //顺子
for (int i = 14; i >= 2; i--)
if (cnt[i] == 3) { //三带一
for (int j = 1; j <= 3; j++)
tmp[p][j].rank = i;
int k = 4;
for (int j = 14; j >= 2; j--)
if (cnt[j] == 1)
tmp[p][k++].rank = j;
return 4;
}
int sum = 0, k = 1;
for (int i = 14; i >= 2; i--)
if (cnt[i] == 2){
sum++;
tmp[p][k++].rank = i;
tmp[p][k++].rank = i;
}
if (sum > 0)
for (int i = 14; i >= 2; i--)
if (cnt[i] == 1)
tmp[p][k++].rank = i;
if (sum == 2)
return 3; //两对对子
else if (sum == 1)
return 2; //对子
else
return 1;
}
int compare() //同tpye下比rank,返回-1Alice赢,返回0平手
{
for (int i = 1; i <= 5; i++)
if (tmp[0][i].rank > tmp[1][i].rank)
return -1;
else if (tmp[0][i].rank < tmp[1][i].rank)
return 1;
return 0;
}
int dfs(int x, int y, int p){
if (x == 4 && y == 4){
for (int i = 1; i <= 5; i++){
tmp[0][i] = A[i];
tmp[1][i] = B[i];
}
sort(tmp[0] + 1, tmp[0] + 6);
sort(tmp[1] + 1, tmp[1] + 6);
int a = getrank(0), b = getrank(1);
if (a != b){
if (a > b)
return -1;
else
return 1;
}
else
return compare();
}
bool flag = 0;
for (int i = 1; i <= 6; i++){
if (mark[i])
continue;
mark[i] = 1;
int res;
if (p == 0){
A[2 + x] = C[i];
res = dfs(x + 1, y, 1);
}
else{
B[2 + y] = C[i];
res = dfs(x, y + 1, 0);
}
mark[i] = 0;
if (res == 1)
return -1;
else if (res == 0)
flag = 1;
}
return flag ? 0 : 1;
}
node read(){
char c1, c2;
cin >> c1 >> c2;
return {rk[c1], rk[c2]};
}
void run()
{
memset(mark, 0, sizeof(mark));
A[1] = read();
A[2] = read();
B[1] = read();
B[2] = read();
for (int i = 1; i <= 6; i++)
C[i] = read();
int res = dfs(1, 1, 0);
if (res == -1)
cout << "Alice";
else if (res == 0)
cout << "Draw";
else
cout << "Bob";
cout << endl;
}
signed main()
{
int T = 1;
init();
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> T;
while (T--)
run();
return 0;
}