zoukankan      html  css  js  c++  java
  • 10.12 两次考试

    上午的有些不可做...

    等我成神犇之后再说吧...

    下午的:

    T1

    原题bzoj网格

     

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    const int mod=20100403;
    const int N=3000006;
    
    ll qpow(ll a,int ci)
    {
        ll ans=1;
        while(ci)
        {
            if(ci&1)
                ans=ans*a%mod;
            a=a*a%mod;
            ci>>=1;
        }
        return ans;
    }
    
    ll jie[N],jieni[N];
    
    void chu()
    {
        jie[0]=1;
        for(int i=1;i<N;++i)
            jie[i]=jie[i-1]*i%mod;
        jieni[N-1]=qpow(jie[N-1],mod-2)%mod;
        for(int i=N-2;i>=1;--i)
            jieni[i]=jieni[i+1]*(ll)(i+1)%mod;
        jieni[0]=1;
    }
    
    int n,m;
    
    inline ll C(int n,int m)
    {
        if(n<0||m<0)
            return 0;
        if(n<m)
            return 0;
        return jie[n]*jieni[m]%mod*jieni[n-m]%mod;
    }
    
    int main(){
    
        chu();
    
        scanf("%d%d",&n,&m);
        printf("%lld", (C(n+m,n)-C(n+m,n+1)+mod)%mod );
    }
    T1

     

     

     

    T2

    首先预处理出来$c_i$为第i口井可以喝的次数

    当前飞到第j次,ans为前j-1次喝到的水,$nu_i$为第i口井前面可以喝的井的数目

    那么第j次第i口井能喝到水,它必须满足 $c_i$-$nu_i$>ans

    那么我们用线段树维护$c_i$-$nu_i$的最小值

    到了第j次飞,我们就把线段树中$c_i$-$nu_i$<=ans的都取出来去掉,并且把i+1~n的值都+1

    一直到第m次或没有满足条件的井了

     

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    inline int read()
    {
        char q=getchar();int ans=0;
        while(q<'0'||q>'9')q=getchar();
        while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
        return ans;
    }
    const int N=100006;
    const int INF=0x7fffffff-1e8;
    
    int n,m;
    int hi;
    int w[N],A[N],ci[N];
    
    struct TTT______TTT
    {
        int mn[N*5],sum[N*5];
        int ji[N*5];
        inline void pushup(int x)
        {
            sum[x]=sum[x<<1]+sum[x<<1|1];
            mn[x]=(mn[x<<1]<mn[x<<1|1]?mn[x<<1]:mn[x<<1|1]);
        }
        void pushdown(int x)
        {
            if(ji[x])
            {
                ji[x<<1]+=ji[x];
                ji[x<<1|1]+=ji[x];
                mn[x<<1]+=ji[x];
                mn[x<<1|1]+=ji[x];
                ji[x]=0;
            }
        }
        void build(int l,int r,int x)
        {
            if(l==r)
            {
                mn[x]=ci[l]-l+1,sum[x]=1;
                return ;
            }
            int mid=(l+r)>>1;
            build(l,mid,x<<1);
            build(mid+1,r,x<<1|1);
            pushup(x);
        }
        void del(int pos,int l,int r,int x)
        {
            if(l==r)
            {
                mn[x]=INF;sum[x]=0;
                return ;
            }
            pushdown(x);
            int mid=(l+r)>>1;
            if(pos<=mid)
                del(pos,l,mid,x<<1);
            else
                del(pos,mid+1,r,x<<1|1);
            pushup(x);
        }
        void add(int L,int R,int l,int r,int x)
        {
            if(L>R)
                return ;
            if(L<=l&&r<=R)
            {
                ++mn[x];++ji[x];
                return ;
            }
            pushdown(x);
            int mid=(l+r)>>1;
            if(L<=mid)
                add(L,R,l,mid,x<<1);
            if(mid<R)
                add(L,R,mid+1,r,x<<1|1);
            pushup(x);
        }
        int qqpos(int val,int l,int r,int x)
        {
            if(l==r)
                return l;
            pushdown(x);
            int mid=(l+r)>>1;
            if(mn[x<<1]==val)
                return qqpos(val,l,mid,x<<1);
            else
                return qqpos(val,mid+1,r,x<<1|1);
        }
    }T;
    
    int work()
    {
        T.build(1,n,1);
        int ans=0,temp;
        for(int i=1;i<=m;++i)
        {
            //printf("i=%d ans=%d
    ",i,ans);
    
            while(T.mn[1]<=ans)
            {
                temp=T.qqpos(T.mn[1],1,n,1);
                //printf("mn=%d pos=%d
    ",T.mn[1],temp);
                T.del(temp,1,n,1);
                T.add(temp+1,n,1,n,1);
                //cout<<0;
            }
            ans+=T.sum[1];
            if(T.sum[1]==0)
                break;
        }
        return ans;
    }
    
    int main(){
    
        freopen("T2.in","r",stdin);
        freopen("T2.out","w",stdout);
    
        n=read();m=read();hi=read();
        for(int i=1;i<=n;++i)
            w[i]=read();
        for(int i=1;i<=n;++i)
            A[i]=read();
        for(int i=1;i<=n;++i)
        {
            ci[i]=(hi-w[i])/A[i]+1;
            if(ci[i]<0)
                ci[i]=0;
        }
    
        /*printf("
    ");
        for(int i=1;i<=n;++i)
            printf("%d ",ci[i]);
        printf("
    ");*/
    
        cout<<work();
    }
    T2

     

     

     

    T3

    先把op==1||op==2的同一行(列)的并查集并起来,这样可以减小建边数量

    然后tarjan一下,求最长链即可

     

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    inline int read()
    {
        char q=getchar();int ans=0;
        while(q<'0'||q>'9')q=getchar();
        while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
        return ans;
    }
    const int N=100006;
    const int RR=1000006;
    const int CC=1000006;
    struct son
    {
        int v,next;
    };
    struct TTT___TTT
    {
        son a1[N*10];
        int first[N*10],e;
        void clear()
        {
            mem(a1,0);
            mem(first,-1);
            e=0;
        }
        void addbian(int u,int v)
        {
            a1[e].v=v;
            a1[e].next=first[u];
            first[u]=e++;
        }
    }h[2];
    struct JI
    {
        int x,y,jian,jia,order;
        int op;
        void boom()
        {
            x=y=jian=jia=op=0x7fffffff;
            order=0;
        }
    }ji[N];
    bool cmp_x(JI a,JI b)
    {
        if(a.x==b.x)
            return a.y<b.y;
        return a.x<b.x;
    }
    bool cmp_y(JI a,JI b)
    {
        if(a.y==b.y)
            return a.x<b.x;
        return a.y<b.y;
    }
    bool cmp_jian(JI a,JI b)
    {
        if(a.jian==b.jian)
            return a.jia<b.jia;
        return a.jian<b.jian;
    }
    bool cmp_jia(JI a,JI b)
    {
        if(a.jia==b.jia)
            return a.jian<b.jian;
        return a.jia<b.jia;
    }
    
    int fa[N];
    int fin(int x)
    {
        if(fa[x]==-1)
            return x;
        fa[x]=fin(fa[x]);
        return fa[x];
    }
    void match(int u,int v)
    {
        int x=fin(u),y=fin(v);
        if(x!=y)
            fa[x]=y;
    }
    
    int n,R,C;
    
    int zhan[N*5],he;
    int num[N];
    
    int dfn[N],low[N],tim;
    bool flag[N];
    int sum,sun[N],dui[N];
    
    int an[N];
    
    void dfs(int x)
    {
        int temp;
        an[x]=sun[x];
        for(int i=h[1].first[x];i!=-1;i=h[1].a1[i].next)
        {
            temp=h[1].a1[i].v;
            if(an[temp])
            {
                if(an[x]<an[temp]+sun[x])
                    an[x]=an[temp]+sun[x];
                continue;
            }
            dfs(temp);
            if(an[x]<an[temp]+sun[x])
                an[x]=an[temp]+sun[x];
        }
    }
    
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tim;
        zhan[++he]=x;flag[x]=1;
        int temp;
        for(int i=h[0].first[x];i!=-1;i=h[0].a1[i].next)
        {
            temp=h[0].a1[i].v;
            if(dfn[temp]==-1)
            {
                tarjan(temp);
                if(low[x]>low[temp])
                    low[x]=low[temp];
            }
            else
                if(flag[temp]&&low[x]>low[temp])
                    low[x]=low[temp];
        }
        if(low[x]==dfn[x])
        {
            ++sum;
            while(1)
            {
                temp=zhan[he--];flag[temp]=0;
                dui[temp]=sum;
                sun[sum]+=num[temp];
                if(temp==x)
                    break;
            }
        }
    }
    
    void out11()
    {
        /*printf("
    ");
        for(int i=1;i<=n;++i)
            printf("%d ",fin(i));
        printf("
    ");*/
        printf("
    ");
        for(int i=1;i<=n;++i)
        {
            printf("i=%d  ",i);
            for(int j=h[0].first[i];j!=-1;j=h[0].a1[j].next)
                printf("%d ",h[0].a1[j].v);
            printf("
    ");
        }
        printf("
    ");
    }
    
    int work()
    {
        ji[0].boom();ji[n+1].boom();
    
    
    
        sort(ji+1,ji+1+n,cmp_x);
        int now,t1,t2;
        for(int i=1;i<=n;i=now+1)
        {
            now=i;he=0;
            while(ji[now].x==ji[i].x&&now<=n)
            {
                if( ji[now].op==1 )
                    zhan[++he]=now;
                ++now;
            }
            --now;
            for(int j=2;j<=he;++j)
                match(ji[zhan[j]].order,ji[zhan[j-1]].order);
        }
        sort(ji+1,ji+1+n,cmp_y);
        for(int i=1;i<=n;i=now+1)
        {
            now=i;he=0;
            while(ji[now].y==ji[i].y&&now<=n)
            {
                if( ji[now].op==2 )
                    zhan[++he]=now;
                ++now;
            }
            --now;
            for(int j=2;j<=he;++j)
                match(ji[zhan[j]].order,ji[zhan[j-1]].order);
        }
    
    
    
        sort(ji+1,ji+1+n,cmp_x);
        for(int i=1;i<=n;i=now+1)
        {
            now=i;he=0;
            while(ji[now].x==ji[i].x&&now<=n)
            {
                if( ji[now].op==1 )
                    zhan[++he]=now;
                ++now;
            }
            --now;
            if(he)
            {
                t1=fin(ji[zhan[1]].order);
                for(int j=i;j<=now;++j)
                {
                    t2=fin(ji[j].order);
                    if(t1!=t2)
                        h[0].addbian(t1,t2);
                }
            }
            for(int j=i;j<=now;++j)
                if(ji[j].op==3)
                {
                    if(ji[j-1].x==ji[j].x&&ji[j-1].y==ji[j].y-1&&fin(ji[j].order)!=fin(ji[j-1].order))
                        h[0].addbian(fin(ji[j].order),fin(ji[j-1].order));
                    if(ji[j+1].x==ji[j].x&&ji[j+1].y==ji[j].y+1&&fin(ji[j].order)!=fin(ji[j+1].order))
                        h[0].addbian(fin(ji[j].order),fin(ji[j+1].order));
                }
        }
    
        sort(ji+1,ji+1+n,cmp_y);
        for(int i=1;i<=n;i=now+1)
        {
            now=i;he=0;
            while(ji[now].y==ji[i].y&&now<=n)
            {
                if( ji[now].op==2 )
                    zhan[++he]=now;
                ++now;
            }
            --now;
            if(he)
            {
                t1=fin(ji[zhan[1]].order);
                for(int j=i;j<=now;++j)
                {
                    t2=fin(ji[j].order);
                    if(t1!=t2)
                        h[0].addbian(t1,t2);
                }
            }
            for(int j=i;j<=now;++j)
                if(ji[j].op==3)
                {
                    if(ji[j-1].y==ji[j].y&&ji[j-1].x==ji[j].x-1&&fin(ji[j].order)!=fin(ji[j-1].order))
                        h[0].addbian(fin(ji[j].order),fin(ji[j-1].order));
                    if(ji[j+1].y==ji[j].y&&ji[j+1].x==ji[j].x+1&&fin(ji[j].order)!=fin(ji[j+1].order))
                        h[0].addbian(fin(ji[j].order),fin(ji[j+1].order));
                }
        }
    
        sort(ji+1,ji+1+n,cmp_jian);
        for(int i=1;i<=n;++i)
            if(ji[i].op==3)
            {
                t1=fin(ji[i].order);
                t2=fin(ji[i-1].order);
                if(ji[i-1].jian==ji[i].jian&&ji[i-1].jia==ji[i].jia-2&&t1!=t2)
                    h[0].addbian(t1,t2);
                t2=fin(ji[i+1].order);
                if(ji[i+1].jian==ji[i].jian&&ji[i+1].jia==ji[i].jia+2&&t1!=t2)
                    h[0].addbian(t1,t2);
            }
        sort(ji+1,ji+1+n,cmp_jia);
        for(int i=1;i<=n;++i)
            if(ji[i].op==3)
            {
                t1=fin(ji[i].order);
                t2=fin(ji[i-1].order);
                if(ji[i-1].jia==ji[i].jia&&ji[i-1].jian==ji[i].jian-2&&t1!=t2)
                    h[0].addbian(t1,t2);
                t2=fin(ji[i+1].order);
                if(ji[i+1].jia==ji[i].jia&&ji[i+1].jian==ji[i].jian+2&&t1!=t2)
                    h[0].addbian(t1,t2);
            }
    
        for(int i=1;i<=n;++i)
            ++num[fin(i)];
        he=0;
        for(int i=1;i<=n;++i)
            if(dfn[i]==-1&&num[i])
                tarjan(i);
        int temp;
        for(int i=1;i<=n;++i)
            if(num[i])
            {
                for(int j=h[0].first[i];j!=-1;j=h[0].a1[j].next)
                {
                    temp=h[0].a1[j].v;
                    if(dui[i]!=dui[temp])
                        h[1].addbian(dui[i],dui[temp]);
                }
            }
    
        //out11();
    
        //printf("sum=%d
    ",sum);
    
        for(int i=1;i<=sum;++i)
            if(!an[i])
                dfs(i);
        int ans=0;
        for(int i=1;i<=sum;++i)
            if(ans<an[i])
                ans=an[i];
        return ans;
    }
    
    int main(){
    
        //freopen("T3.in","r",stdin);
    
        mem(fa,-1);
        mem(dfn,-1);
        h[0].clear();
        h[1].clear();
    
        n=read();R=read();C=read();
        for(int i=1;i<=n;++i)
        {
            ji[i].x=read();
            ji[i].y=read();
            ji[i].op=read();
            ji[i].jia=ji[i].x+ji[i].y;
            ji[i].jian=ji[i].x-ji[i].y;
            ji[i].order=i;
        }
    
        /*printf("
    ");
        for(int i=1;i<=n;++i)
            printf("%d %d %d
    ",ji[i].x,ji[i].y,ji[i].op);
        printf("
    ");*/
    
        cout<<work();
    }
    T3

     

     

    总结:

    多考虑每个题成立的条件,不要无头绪的乱想

    还有打程序要严谨...一遍对...

     

  • 相关阅读:
    PAT Basic 1077 互评成绩计算 (20 分)
    PAT Basic 1055 集体照 (25 分)
    PAT Basic 1059 C语言竞赛 (20 分)
    PAT Basic 1072 开学寄语 (20 分)
    PAT Basic 1049 数列的片段和 (20 分)
    蓝桥杯BASIC-13 数列排序
    蓝桥杯入门——3.序列求和
    蓝桥杯入门——2.圆的面积
    蓝桥杯入门——1.Fibonacci数列
    树的总结(遍历,BST,AVL原型,堆,练习题)
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7657956.html
Copyright © 2011-2022 走看看