2017-11-7离线赛总结

来源:互联网 发布:普罗米修斯软件 编辑:程序博客网 时间:2024/05/18 02:11

    • 题目
    • 失分小结
      • 估分
      • 实际分数
    • 题解
      • T1
        • P100
          • CODE
      • T2
        • P95
          • CODE
        • P100
          • CODE
      • T3
        • P100
          • CODE

题目

3814,3815,3816

失分小结

估分

100+100+?≈210

实际分数

0+100+10=110
第一题输出调试没关啊啊啊爆零

题解

T1

P100

玄学贪心.

CODE
#include<cstdio>#include<iostream>using namespace std;#define N 100005int A[N];int main() {    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%d",A+i);    long long num=A[2]>A[1]?A[2]-A[1]:A[1]-A[2];    for(int i=3;i<=n;i++){        if(A[i]>=A[i-1]&&A[i-1]>=A[i-2])            num+=A[i]-A[i-1];        else if(A[i]<=A[i-1]&&A[i-1]<=A[i-2]){            num+=A[i-1]-A[i];        }        else if(A[i]<=A[i-1]&&A[i-1]>=A[i-2]){            A[i-1]=max(A[i],A[i-2]);            num+=A[i-1]-A[i];        }        else if(A[i]>=A[i-1]&&A[i-1]<=A[i-2]){            A[i-1]=min(A[i],A[i-2]);            num+=A[i]-A[i-1];        }    }    /*    for(int i=1;i<=n;i++)printf("%d ",A[i]);    puts("");    *///输出调试啊啊啊    printf("%lld\n",num);    return 0;}

T2

保存所有的点的子树大小size

ans=ni=1sizei×(nsizei)×lenthn×(n1)/6

不少人long long炸成P80,还要double.

P95

CODE
//注意会炸long long!!!网站上95.当然本地测试还是有100的啦#include<cstdio>#include<memory.h>#define N 500005struct node2 {int to,len,nxt;} edge[N<<1];int head[N],tot;int fa[N],sz[N];void dfs1(int x,int f) {    fa[x]=f;    sz[x]=1;    for(int i=head[x]; ~i; i=edge[i].nxt) {        node2 y=edge[i];        if(y.to==f)continue;        dfs1(y.to,x);        sz[x]+=sz[y.to];    }}int n,m;long long ans=0;void dfs(int x) {    for(int i=head[x]; ~i; i=edge[i].nxt) {        int y=edge[i].to;        if(y==fa[x])continue;        long long t=1ll*sz[y]*(n-sz[y]);        ans+=t*edge[i].len;        dfs(y);    }}int main() {    int a,b,c;    scanf("%d",&n);    memset(head,-1,sizeof head);    for(int i=1; i<n; i++) {        scanf("%d %d %d",&a,&b,&c);        edge[tot]=(node2) {b,c,head[a]},head[a]=tot++;        edge[tot]=(node2) {a,c,head[b]},head[b]=tot++;    }    dfs1(1,-1);    dfs(1);    printf("%.2lf\n",6.0*ans/n/(n-1));    return 0;}

P100

long long改成double,顺便把一些累赘的代码去掉.

CODE
#include<cstdio>#include<memory.h>#define N 500005struct node {int to,len,nxt;} edge[N<<1];int head[N],tot;int n,m;int sz[N];double ans=0;void dfs(int x,int f) {    sz[x]=1;    for(int i=head[x]; ~i; i=edge[i].nxt) {        int y=edge[i].to;        if(y==f)continue;        dfs(y,x);        sz[x]+=sz[y];        ans+=(double)sz[y]*(n-sz[y])*edge[i].len;    }}int main() {    int a,b,c;    scanf("%d",&n);    memset(head,-1,sizeof head);    for(int i=1; i<n; i++) {        scanf("%d %d %d",&a,&b,&c);        edge[tot]=(node) {b,c,head[a]},head[a]=tot++;        edge[tot]=(node) {a,c,head[b]},head[b]=tot++;    }    dfs(1,-1);    printf("%.2lf\n",6.0*ans/n/(n-1));    return 0;}

T3

P100

玄学高精.常数优化!!!万进制可能卡不过去…亿进制600ms左右,十亿进制500ms左右(很多同学都只有300ms~400ms,一定是我太弱了)
当然n=3时由于长度一直为3按正常方法会超时于是特判改用快速幂.

CODE
#include<iostream>#include<cstring>#include<cstdio>#define P 1000000000//1e9#define reg register#define FOR(i,a,b) for(reg int i=(a),i##_END_=(b);i<=i##_END_;i++)#define ROF(i,a,b) for(reg int i=(a),i##_END_=(b);i>=i##_END_;i--)typedef long long ll;using namespace std;int n;struct Bignum {    int len;    ll num[10086];    Bignum() {len=1;memset(num,0,sizeof num);}    void Rd() {        char C[1005];        scanf("%s",C+1);        int n=strlen(C+1);        len=0;        for(int i=n; i>=1; i-=9) {            len++;            num[len]=0;            for(int j=max(1,i-8); j<=i; j++) {                num[len]=(num[len]<<3)+(num[len]<<1)+(C[j]^48);            }        }        while(!num[len])len--;    }    void print() {        printf("%lld",num[len]);        for(int i=len-1; i>=1; i--)printf("%09lld",num[i]);        puts("");    }    Bignum operator +(const Bignum &_)const {        Bignum Ans;        Ans.len=max(_.len,len);        for(reg int i=1; i<=Ans.len; i++) {            Ans.num[i]+=num[i]+_.num[i];            if(Ans.num[i]>=P) {                Ans.num[i]-=P;                Ans.num[i+1]++;            }        }        if(Ans.num[Ans.len+1])Ans.len++;        return Ans;    }    Bignum operator -(const Bignum &_)const {        Bignum Ans;        Ans.len=max(_.len,len);        FOR(i,1,Ans.len) {            Ans.num[i]+=num[i]-_.num[i];            if(Ans.num[i]<0) {                Ans.num[i]+=P;                Ans.num[i+1]--;            }        }        while(!Ans.num[Ans.len]&&len>1)Ans.len--;        return Ans;    }    void operator++ () {        num[1]++;        FOR(i,1,len) {            if(num[i]>=P) {                num[i]-=P;                num[i+1]++;            } else break;        }        if(num[len+1])len++;    }    void operator-- () {        num[1]--;        FOR(i,1,len) {            if(num[i]<0) {                num[i]+=P;                num[i+1]--;            } else break;        }        while(!num[len]&&len>1)len--;    }    Bignum operator *(const Bignum &_)const {        Bignum Ans;        Ans.len=_.len+len-1;        FOR(i,1,len)FOR(j,1,_.len) {            Ans.num[i+j-1]+=num[i]*_.num[j];            if(Ans.num[i+j-1]>=P) {                Ans.num[i+j]+=Ans.num[i+j-1]/P;                Ans.num[i+j-1]%=P;            }        }        while(Ans.num[Ans.len+1])Ans.len++;        return Ans;    }    bool operator <=(const Bignum &_)const {        if(_.len!=len)return len<_.len;        ROF(i,len,1)if(num[i]!=_.num[i])            return num[i]<_.num[i];        return 1;    }} k;struct P100 {    void solve() {        k.Rd();        Bignum mi,mx,c;        mi.num[1]=1,mx.num[1]=n;        c=mx-mi;++c;        if(k<=c) {            Bignum ans;            ans=mi+k;--ans;            ans.print();        } else {            k=k-c;            while(1) {                mi=mi+mi;++mi;                mx=mx+mx;--mx;                c=mx-mi;++c;                if(k<=c)break;                else k=k-c;            }            Bignum ans;            ans=mi+k;            --ans;            ans.print();        }    }} pother;struct Pn3 {    void solve() {        int k;        Bignum a;        a.num[1]=2;        Bignum ans;        ans.num[1]=1;        scanf("%d",&k);        int tmp=(k-1)/3+1;        while(tmp) {            if(tmp&1)ans=ans*a;            tmp>>=1;            if(!tmp)break;            a=a*a;        }        if(k%3==1)--ans;        else if(!(k%3))++ans;        ans.print();    }} nequ3;int main() {    scanf("%d",&n);    if(n==3)nequ3.solve();    else if(n<=2) {        k.Rd();        if(n==2&&k.len==1&&k.num[1]==1)puts("1");        else if(n==2&&k.len==1&&k.num[1]==2)puts("2");        else if(n==2&&k.len==1&&k.num[1]==3)puts("3");        else puts("-1");    } else pother.solve();    return 0;}