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
",ans);
    }
    return 0;
}
View Code

D题:这是个无聊的水题。。去一下对数用long double然后排序一下就行了,这里注意取一阶对数,另外一阶直接用pow。。

/*
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 double EPS=1e-10;

long double x,y,z;

long double f1(long double x,long double y,long double z)
{
    return pow(y,z)*log(x);
}

long double f2(long double x,long double y,long double z)
{
    return y*z*log(x);
}

struct Node
{
    long double v;
    int id;
    friend bool operator<(Node A,Node B)
    {
        if(A.v>B.v+EPS) return 1;
        if(fabs(A.v-B.v)<EPS) return A.id<B.id;
        return 0;
    }
};Node a[20];int n;
const string s[14]=
{
    "","x^y^z","x^z^y","(x^y)^z","(x^z)^y",
       "y^x^z","y^z^x","(y^x)^z","(y^z)^x",
       "z^x^y","z^y^x","(z^x)^y","(z^y)^x",
};

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>x>>y>>z){
        n=12;
        REP(i,1,n) a[i].id=i;
        a[1].v=f1(x,y,z);
        a[2].v=f1(x,z,y);
        a[3].v=f2(x,y,z);
        a[4].v=f2(x,z,y);
        a[5].v=f1(y,x,z);
        a[6].v=f1(y,z,x);
        a[7].v=f2(y,x,z);
        a[8].v=f2(y,z,x);
        a[9].v=f1(z,x,y);
        a[10].v=f1(z,y,x);
        a[11].v=f2(z,x,y);
        a[12].v=f2(z,y,x);
        sort(a+1,a+n+1);
        if(a[1].id==4||a[1].id==8||a[1].id==12) a[1].id--;
        cout<<s[a[1].id]<<endl;
    }
    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

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

没有AC不了的题,只有不努力的ACMER!
原文地址:https://www.cnblogs.com/--560/p/5174334.html