暑期个人赛第一场

6 篇文章 0 订阅
4 篇文章 0 订阅

不知不觉假期即将接近尾声,而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;
}


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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值