codeforces#341

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces#341相关的知识,希望对你有一定的参考价值。

A题:偶数直接加进去,奇数排序后去掉最小的即可。

技术分享
/*
ID: NotPassedCET4
PROG: #341
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

ll o[maxn],on,e[maxn],en;
int n;

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n){
        on=en=0;
        REP(i,1,n){
            ll x;scanf("%I64d",&x);
            if(x&1) o[++on]=x;
            else e[++en]=x;
        }
        ll s=0;
        sort(o+1,o+on+1);
        REP(i,1,en) s+=e[i];
        int k=1;
        if(on&1) k=2;
        for(int i=on;i>=k;i--) s+=o[i];
        cout<<s<<endl;
    }
    return 0;
}
View Code

B题:由于主对角线和辅对角线对结果的影响是独立,所以分开找即可,对每个对角线内的k个棋子,对答案的贡献是C(k,2)。

技术分享
/*
ID: NotPassedCET4
PROG: #341
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n;
struct Node
{
    int x,y;
    int z,w;
};Node p[maxn];

bool cmpz(Node A,Node B)
{
    return A.z<B.z;
}

bool cmpw(Node A,Node B)
{
    return A.w<B.w;
}

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n){
        REP(i,1,n) scanf("%d%d",&p[i].x,&p[i].y);
        REP(i,1,n){
            p[i].z=p[i].x+p[i].y-1;
            p[i].w=p[i].x-p[i].y;
        }
        sort(p+1,p+n+1,cmpz);
        ll ans=0;
        for(int i=1;i<=n;){
            int j=i;
            while(j<=n&&p[j].z==p[i].z) j++;
            ll cnt=j-i;
            ans+=cnt*(cnt-1)/2;
            i=j;
        }
        sort(p+1,p+n+1,cmpw);
        for(int i=1;i<=n;){
            int j=i;
            while(j<=n&&p[j].w==p[i].w) j++;
            ll cnt=j-i;
            ans+=cnt*(cnt-1)/2;
            i=j;
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

C题:对每个个体单独计算对答案的贡献期望即可,算是数学题吧。。写的时候碰到两个问题,一是算边界的时候用了二分,其实直接前缀和f(r)-f(l-1)即可,其中f(x)=x/p;另外一个是式子没写清楚,分母写错了。。

技术分享
/*
ID: NotPassedCET4
PROG: #341
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n;ll pt;
struct Node
{
    ll l,r;
    ll len;
    ll x,y;
    void read()
    {
        scanf("%I64d%I64d",&l,&r);
        len=r-l+1;
        x=r/pt-(l-1)/pt;
        y=len-x;
    }
};Node p[maxn];

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n>>pt){
        REP(i,1,n){
            p[i].read();
        }
        double ans=0;
        REP(i,1,n){
            int j=i-1,k=i+1;
            if(j==0) j=n;
            if(k==n+1) k=1;
            double tmp=0;
            tmp+=(1.0*p[j].len*p[i].x*p[k].len+1.0*p[j].x*p[i].y*p[k].x)*2000;
            tmp+=(1.0*p[j].y*p[i].y*p[k].x+1.0*p[j].x*p[i].y*p[k].y)*1000;
            tmp/=1.0*p[j].len*p[i].len*p[k].len;
            ans+=tmp;
        }
        printf("%.8f\n",ans);
    }
    return 0;
}
View Code

E题:很容易写出dp方程,前i位余数为j的方案数为 dp[i][j]=dp[i-1][k]*cnt[t],其中j=(k*10+t)%x,i范围最大可到1e9,因此只有快速幂了。

先解出t=(j-10*k)%x;

那么为了方便快速幂,方程简化一下:f[i]=f[j]*cnt[(i-10*j)%x]。(0<=i<x)

f[i]为当前项,f[j]为前一项,显然转移矩阵为A[i][j]=cnt[(i-10*j)%x],这样问题就解决了。

大概如下。。。

| f[0] |              | A[0][0]  A[0][1]....         A[0][x-1]   |         | f[0] |

| f[1] |         =   |                                                     |        | f[1] |

| .   |               |                                                 |      *     |   .  |

|   .   |              |                                                   |          |    .  |

| f[x-1] |           |A[x-1][0] ............        A[x-1][x-1] |           | f[x-1]  |

技术分享
/*
ID: NotPassedCET4
PROG: #341
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;
const ll p=1e9+7;

const int N=102;
ll n,b,k,x;
struct Matrix
{
    ll a[N][N];
    friend Matrix operator*(Matrix A,Matrix B)
    {
        Matrix res={};
        REP(i,0,x-1){
            REP(j,0,x-1){
                REP(k,0,x-1){
                    res.a[i][j]=(res.a[i][j]+((A.a[i][k]%p)*(B.a[k][j]%p))%p)%p;
                }
            }
        }
        return res;
    }
};
ll cnt[N];
ll Fs[N],Ft[N];

Matrix qpow(Matrix n,ll k)
{
    Matrix res={};
    REP(i,0,x-1) res.a[i][i]=1;
    while(k){
        if(k&1) res=res*n;
        n=n*n;
        k>>=1;
    }
    return res;
}

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n>>b>>k>>x){
        MS0(cnt);
        REP(i,1,n){
            int y;scanf("%d",&y);
            cnt[y%x]++;
        }
        REP(i,0,x-1) Fs[i]=cnt[i],Ft[i]=0;
        Matrix A;
        REP(i,0,x-1){
            REP(j,0,x-1){
                A.a[i][j]=cnt[(i+10*x-10*j)%x];
            }
        }
        A=qpow(A,b-1);
        REP(i,0,x-1){
            REP(j,0,x-1){
                Ft[i]=(((Fs[j]%p)*(A.a[i][j]%p))%p+Ft[i]%p)%p;
            }
        }
        cout<<Ft[k]<<endl;
    }
    return 0;
}
View Code

 

总结,代码速度和准确性并不算太差,但是用在分析的时间较少,对题目没有充分的分析和判断就直接写了,这导致比赛中常常选择不合理的思路。不过已经慢慢找回状态了。

 

以上是关于codeforces#341的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #341 (Div. 2) ABCDE

Codeforces Round #341 (Div. 2)

Codeforces Round #341 Div.2 B. Wet Shark and Bishops

Codeforces Round #341 Div.2 C. Wet Shark and Flowers

Codeforces Round #341 Div.2 A. Wet Shark and Odd and Even

Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks(矩阵优化DP)