暑期个人赛第一场

来源:互联网 发布:如何创建java集合类 编辑:程序博客网 时间:2024/05/16 12:37

不知不觉假期即将接近尾声,而icpc之路也开始了最后的冲刺

作为大三老油条,从未参加过现场赛,有点惭愧,确实上届队员还是不少的,导致去年整个大一都没获得什么机会,那今年就是最好的机会了,那么就从个人赛开始吧


这次个人赛,由于和数模相冲,并没能完整,不过补题还是不能少的,毕竟是校队成员辛苦出的,你说是吧,那就补一下前两题吧


A 1233 Glory and LCS

思路:这题乍一看,就是个lcs问题,然而绞尽脑汁还是没能想出快于O(n^2)的lcs算法。

再仔细看题,两个目标串皆为全排列,那么完全可以将两个串对应成一个串,然后转换成对新串求lis

求lis是有O(nlog(n))的算法的,dp+二分,于是瞬间豁然开朗

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>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定理降一下计算量,顺便套个快速幂的板子

由于模数不为质数,再用一下中国剩余

综合来看,这题确实考了不少知识点

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>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;}

第一场个人赛,一个队友拿到了榜眼,是个好兆头,加油

文章地址:http://blog.csdn.net/owen_q/article/details/78054665

原创粉丝点击