Don't fake it till you made it

Fake it till you become it

2017.7.22模拟赛被虐记录

感觉自己要完
成功被虐了两倍分。。
其实故事是这样的
看了第二题 发现是个SB树分
然后就没有然后了
突然Manchery说自己的代码会被卡常 然后我拿了大样例 没开优化跑了0.8s 时限2s 感觉很稳啊
看了第一题 完全没思路 看了看大样例 我日 SB题。。。 但是要特判几个hack点。。。
第三题 弃疗 暴力都不会。。。
然后。。。本机跑0.8s的我在评测机上2s TLE…
然而本机比我慢的Manchery就就就轻轻松松跑过去了
日 EXM?什么破机子 被卡常了
map真TM的慢。。早知道就不图方便自己打个数组记录

第一题 特判成功没考虑重复情况 成功gg

然后因为蜜汁数据打包问题。。。。
200 -> 70
EXM?200分rank2啊
感觉自己好弱啊QaQ

T1:找规律

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<map>
using namespace std;
#define Com complex<double>
const
    double pi=acos(-1);
char c;
#define ll long long
inline void read(ll &a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
ll a[100001];
ll P[100001];
const   int MAXN=2233333;
int Tot,prime[MAXN+1];
bool ck[MAXN+1];
bool Has[MAXN+1];
int main()
{
    for(int i=2;i<=MAXN;i++)
    {
        if(!ck[i])prime[++Tot]=i;
        for(int j=1,k=2*i;j<=Tot&&k<=MAXN;k=prime[++j]*i)
        {
            ck[k]=true;
            if(i%prime[j]==0)break;

        }
    }
    ll n,x;
    read(n),read(x);
    for(int i=1;i<=n;i++)read(a[i]),Has[a[i]>MAXN?0:a[i]]=true;

    sort(a+1,a+1+n);
    n=unique(a+1,a+1+n)-a-1;
    if(x==2){return puts("0"),0;}
    if(a[1]==1){return puts("1"),0;}
    if(a[1]!=2){return puts("-1"),0;}
    if(x==3){return puts("1"),0;}
    if(a[2]!=3){return puts("-1"),0;}
    if(n==1){return puts("-1"),0;}

    if(prime[n+1]<x){return puts("-1"),0;}

    int tot=0;
    for(int i=1;prime[i]<x;i++)
    {
        if(!Has[prime[i]]){return puts("-1"),0;}
        tot++;
    }
    cout<<tot<<endl;
    return 0;
}

T2:
Sol1:O(nlogn)可持久化线段树加堆
Sol2:O(nlog2n)点分树+超级钢琴
Sol3:O(nlog2n)点分树+二分答案+Two Pointer累加

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<map>
using namespace std;
#define Com complex<double>
const
    double pi=acos(-1);
char c;
inline void read(int&a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Chain
{
    int u,len;  
    Chain*next;
}*Head[100001];

inline void Add(int u,int v,int len)
{
    Chain*tp=new Chain;
    tp->u=v;
    tp->len=len;
    tp->next=Head[u];
    Head[u]=tp;
}

int All[5000001],Cur;
int SonBG[50001],SonED[50001],SubBG[50001],SubED[50001];

int Size[50001];
bool done[50001];
void GetSize(int u,int f)
{
    Size[u]=1;
    for(Chain*tp=Head[u];tp;tp=tp->next)
        if(tp->u^f&&!done[tp->u])GetSize(tp->u,u),Size[u]+=Size[tp->u];
}

int Rt,MX[50001],SUM;
void GetRoot(int u,int f)
{
    MX[u]=SUM-Size[u];
    for(Chain*tp=Head[u];tp;tp=tp->next)
        if(tp->u^f&&!done[tp->u])
            GetRoot(tp->u,u),MX[u]=max(MX[u],Size[tp->u]);
    if(MX[Rt]>MX[u])Rt=u;
}
int Cache[50001],tot;
bool Vis[50001];
int M;
void DFS(int u,int f,int Len)
{
    Cache[++tot]=Len,M=max(M,Len);
    for(Chain*tp=Head[u];tp;tp=tp->next)
    if(tp->u^f&&!done[tp->u])
        DFS(tp->u,u,Len+tp->len);
}
int Sont;
int F[200001],U[200001];
void Div(int u)
{

    done[u]=true;
    int t=Cur+1;
    for(Chain*tp=Head[u];tp;tp=tp->next)
    if(!done[tp->u])
    {
        tot=0;
        DFS(tp->u,u,tp->len);
        ++Sont;
        F[Sont]=u;
        U[Sont]=tp->u;
        SonBG[Sont]=1+Cur;
        for(int i=1;i<=tot;i++)
            All[++Cur]=Cache[i];
        SonED[Sont]=Cur;
        sort(All+SonBG[Sont],All+SonED[Sont]+1);
    }
    SubBG[u]=Cur+1;
    int MX=Cur;
    for(int i=t;i<=MX;i++)
        All[++Cur]=All[i];
    All[++Cur]=0;
    SubED[u]=Cur;

    sort(All+SubBG[u],All+SubED[u]+1);
    for(Chain*tp=Head[u];tp;tp=tp->next)
    if(!done[tp->u])
    {
        GetSize(tp->u,u);
        SUM=Size[tp->u];
        Rt=0;
        GetRoot(tp->u,u);
        Div(Rt);
    }
}


int n,m;
bool Query(int LEN)
{
    int Cnt=0;
    for(int i=1;i<=n;i++)
    {
        int *Data=All+SubBG[i]-1;
        int Y=SubED[i]-SubBG[i]+1,MAX=Y,X=Y-1;
        if(X<1||Data[X]+Data[Y]<LEN)continue;
        while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;  
        while(X<Y)
        {
            while(X<Y&&Data[X]+Data[Y]<LEN)X++;
            Cnt+=Y-X;
            Y--;
        }

    }
    if(Cnt<m)return false;
    for(int i=1;i<=Sont;i++)
    {
        int *Data=All+SonBG[i]-1;
        int Y=SonED[i]-SonBG[i]+1,MAX=Y,X=Y-1;
        if(X<1||Data[X]+Data[Y]<LEN)continue;
        while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;
        while(X<Y)
        {
            while(X<Y&&Data[X]+Data[Y]<LEN)X++;
            Cnt-=Y-X;
            Y--;
            if(Cnt<m)return false;
        }
    }
    return Cnt>=m?true:false;

}

//map<int,int>Val;
inline bool cmp(int a,int b){return abs(a)>abs(b);}
int Val[1000001],P;
void COUT(int LEN)
{
    for(int i=1;i<=n;i++)
    {
        int *Data=All+SubBG[i]-1;
        int Y=SubED[i]-SubBG[i]+1,MAX=Y,X=Y-1;
        if(X<1||Data[X]+Data[Y]<LEN)continue;
        while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;

        while(X<Y)
        {
            while(X<Y&&Data[X]+Data[Y]<LEN)X++;
            for(int t=Y-1;t>=X;t--)
                Val[++P]=Data[Y]+Data[t];
            //Cnt+=Y-X;
            Y--;
        }

    }

    for(int i=1;i<=Sont;i++)
    {
        int *Data=All+SonBG[i]-1;
        int Y=SonED[i]-SonBG[i]+1,MAX=Y,X=Y-1;
        if(X<1||Data[X]+Data[Y]<LEN)continue;
        while(X>1&&Data[X-1]+Data[Y]>=LEN)X--;
        while(X<Y)
        {
            while(X<Y&&Data[X]+Data[Y]<LEN)X++;
            for(int t=Y-1;t>=X;t--)
                Val[++P]=-(Data[Y]+Data[t]);
            Y--;
        }
    }
    sort(Val+1,Val+1+P,cmp);
    int t=0,k;
    for(int i=1;i<=P;i=t+1)
    {
        t=i,k=Val[i];
        while(t<P&&(!cmp(Val[t],Val[t+1]))&&!cmp(Val[t+1],Val[t]))
            k+=Val[++t];
        int p=k/abs(Val[i]),o=abs(Val[i]);
        for(int i=1;i<=p;i++)
            printf("%d\n",o);
    }
}

int main()
{

    read(n),read(m);
    for(int i=2;i<=n;i++)
    {
        int a,b,c;
        read(a),read(b),read(c);
        Add(a,b,c),Add(b,a,c);
    }
    GetSize(1,1);
    SUM=n;
    MX[Rt=0]=n*2;
    //SonBG[Rt]=1;
    GetRoot(1,1);
    Div(Rt);
    int L=1,R=M*2,Mid;
    while(L<R)
    {
        Mid=L+R>>1;
        Mid++;
        if(Query(Mid))L=Mid;
        else R=Mid-1;
    }
    //return 0;
    COUT(L);
    return 0;
}

T3:考虑数字0与1出现情况
0只能由1得出
1可以由0或1得出
压缩01的状态 发现若最终态合法则可行

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;

char c;
inline void read(int&a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}

int a[100021],n;
bool ck()
{
    int i;
    while(n>1)
    {
        if(!a[i])a[1]=2;
        if(a[n]==1)n--;
        else if(a[n]==3)a[n]=2;
        for(i=n;i;i--)
            if(!a[i])
            {
                if(a[i-1]==1)
                    a[i-1]=2,a[i]=-1;
                else if(a[i-1]==3)
                    a[i-1]=2,a[i]=2;
                else return false;
            }
        int tmp=0;
        for(i=1;i<=n;i++)
            if(a[i]!=-1)
                a[++tmp]]=a[i];
        n=tmp;
        for(i=1;i<=n;i++)
            a[i]--;
    }
    return true;
}

int main()
{
    int T,i,n;
    for(scanf("%d",&T);T;T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",a+i);
        puts(ck()?"TAK":"NIE");
    }

}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liutian429073576/article/details/56494445
个人分类: 杂文
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

2017.7.22模拟赛被虐记录

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭