不知不觉假期即将接近尾声,而icpc之路也开始了最后的冲刺
作为大三老油条,从未参加过现场赛,有点惭愧,确实上届队员还是不少的,导致去年整个大一都没获得什么机会,那今年就是最好的机会了,那么就从个人赛开始吧
这次个人赛,由于和数模相冲,并没能完整,不过补题还是不能少的,毕竟是校队成员辛苦出的,那就补一下前两题吧
A 1233 Glory and LCS
思路:这题乍一看,就是个lcs问题,然而绞尽脑汁还是没能想出快于O(n^2)的lcs算法。
再仔细看题,两个目标串皆为全排列,那么完全可以将两个串对应成一个串,然后转换成对新串求lis
求lis是有O(nlog(n))的算法的,dp+二分,于是瞬间豁然开朗
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int a[maxn],num[maxn],s[maxn];
int n;
int BSearch(int x, int y, int v)
{
while(x <= y)
{
int mid = x+(y-x)/2;
if(s[mid] <= v) x = mid+1;
else y = mid-1;
}
return x;
}
int dp()
{
for(int i=1;i<=n;i++)
{
s[i] = 1e9;
}
int ans = 0;
for(int i = 1; i <= n; i++)
{
int x = 1, y = i;
int pos = BSearch(x, y, num[i]);
s[pos] = min(s[pos], num[i]);
ans = max(ans, pos);
}
return ans;
}
int main()
{
int t;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int temp;
scanf("%d",&temp);
a[temp] = i;
}
for(int i=1;i<=n;i++)
{
int temp;
scanf("%d",&temp);
num[i] = a[temp];
}
printf("%d\n",dp());
}
}
return 0;
}
B 1227 Godv的数列
思路:经分析不难发现这就是个杨辉三角数列问题,就是a[i] = c(i)(n),当然直接用组合数公式求解
由于数过大,考虑用lucas定理降一下计算量,顺便套个快速幂的板子
由于模数不为质数,需将模数分解质因数,再用一下中国剩余合并一下
综合来看,这题确实考了不少知识点
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
const int mod = 1001;
int mode[3] = {7,11,13};
long long sum[3] = {0};
//long long aa[maxn];
/*long long gcd(long long a,long long b, long long &x,long long &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
else
{
long long r = gcd(b,a%b,y,x);
y -= x * (a / b);
return r;
}
}
long long ni(long long a,long long n)
{
long long x, y;
long long d = gcd(a, n, x, y);
long long ans;
if(d == 1)
{
x %= n;
x += n;
x %= n;
ans = (x % n);
return ans;
}
else
{
//cout << a<<"*"<<n << "*" << d << endl;
return -1;
}
}*/
/*long long c[50][50][3];
long long cc[50][50];
long long lucas(long long a,long long b,int k)
{
long long ans = 1;
while(a && b && ans)
{
ans = (ans * c[a%mode[k]][b%mode[k]][k])%mode[k];
a /= mode[k];
b /= mode[k];
}
return ans;
}
*/
long long gcd(long long a0,long long b0, long long &x,long long &y)
{
if(b0 == 0)
{
x = 1;
y = 0;
return a0;
}
else
{
long long r = gcd(b0,a0%b0,y,x);
y -= x * (a0 / b0);
return r;
}
}
typedef long long LL;
LL Power_mod(LL a, LL b, LL p)
{
LL res = 1;
while(b!=0)
{
if(b&1) res = (res*a)%p;
a = (a*a)%p;
b >>= 1;
}
return res;
}
LL Comb(LL a,LL b, LL p)
{
if(a < b) return 0;
if(a == b) return 1;
if(b > a-b) b = a-b;
LL ans = 1, ca = 1, cb = 1;
for(LL i=0; i<b; ++i)
{
ca = (ca*(a-i))%p;
cb = (cb*(b-i))%p;
}
ans = (ca*Power_mod(cb, p-2, p))%p;
return ans;
}
LL Lucas(int n, int m, int p)
{
LL ans = 1;
while(n && m && ans)
{
ans = (ans * Comb(n%p, m%p, p))%p;
n /= p;
m /= p;
}
return ans;
}
long long CRT(int k)
{
long long N = 1;
for(int i=0; i<k; i++)
{
N = N * mode[i];
}
long long ret = 0;
for(int i=0; i<k; i++)
{
long long x,y;
long long tm = N / mode[i];
gcd(tm, mode[i], x, y);
ret = (ret + tm * x * sum[i]) % N;
}
return (ret + N) % N;
}
int main()
{
int t;
//freopen("test.in","r",stdin);
//freopen("my.out","w",stdout);
//freopen("yhmode.out","w",stdout);
/* for(int k=0;k<3;k++)
{
c[0][0][k] = 1;
for(int i=1;i<15;i++)
{
c[i][0][k] = 1;
for(int j=1;j<i;j++)
{
c[i][j][k] = (c[i-1][j-1][k] + c[i-1][j][k]) % mode[k];
}
c[i][i][k] = 1;
}
}*/
/*cc[0][0] = 1;
for(int i=1;i<15;i++)
{
cc[i][0] = 1;
for(int j=1;j<i;j++)
{
cc[i][j] = (cc[i-1][j-1] + cc[i-1][j]);
}
cc[i][i] = 1;
}
for(int k=0;k<3;k++)
{
c[0][0][k] = 1;
for(int i=1;i<15;i++)
{
c[i][0][k] = 1;
for(int j=1;j<i;j++)
{
c[i][j][k] = cc[i][j] % mode[k];
}
c[i][i][k] = 1;
}
}*/
/*for(int k=0;k<3;k++)
{
for(int i=0;i<15;i++)
{
for(int j=i;j<15;j++)
{
cout << " ";
}
for(int j=0;j<=i;j++)
{
printf("%2d",c[i][j][k]);
}
cout << endl;
}
}*/
//cout << lucas(1003,2);
while(scanf("%d",&t)!=EOF)
{
/*for(int i=0;i<14;i++)
{
cout << c[14][i]<<endl;
}*/
while(t--)
{
int n;
scanf("%d",&n);
sum[0] = 0;
sum[1] = 0;
sum[2] = 0;
for(int i=0;i<n;i++)
{
long long temp;
scanf("%lld",&temp);
for(int k=0;k<3;k++)
{
sum[k] = (sum[k] + (temp * Lucas(n-1,i,mode[k])) %mode[k])%mode[k];
}
}
//cout <<sum[0] <<" "<< sum[1]<<" " << sum[2] << endl;
/*if(n==1)
{
int temp;
scanf("%d",&temp);
printf("%d\n",temp);
}
else
{
int sum = 0;
int pos = 1;
for(int i=0;i<n;i++)
{
scanf("%lld",&aa[i]);
}
for(int i=0;i<n/2;i++)
{
aa[i] += aa[n-i-1];
}
for(int i=0;i<(n+1)/2;i++)
{
aa[i] %= mode;
sum += (pos * aa[i]) % mode;
pos = pos * (n-1-i )% mode;
long long nid = ni(i+1,mode);
//cout << nid << "*" << endl;
if(nid == -1)
{
long long x,y;
long long gcdd = gcd(i+1,mode,x,y);
pos /= gcdd;
nid = ni((i+1)/gcdd,mode);
}
pos = pos * nid % mode;
//cout << pos << endl;
}*/
printf("%d\n",CRT(3));
}
}
return 0;
}
第一场个人赛,一个队友拿到了榜眼,是个好兆头,加油