• 9.29 考试


    题做得有点懵B,过来写个题解吧...

    T1

    我只能说思(ji)路(qi)奇(gou)妙(shi)

    强制在线就是tmd个幌子

    其实是根据las=0 OR 质数,然后反解出opt(神神神%%%)

    除了最后一个操作是 询问需要暴力sort外,其他都是推出来的

     

     

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define ll long long
    using namespace std;
    const int N=200006;
    const int MAXVAL=1000006;
    
    int prime[MAXVAL],cnt;
    bool he[MAXVAL];
    void get_prime()
    {
        for(int i=2;i<MAXVAL;++i)
        {
            if(!he[i])
                prime[++cnt]=i;
            for(int j=1;j<=cnt&&prime[j]*i<MAXVAL;++j)
            {
                he[prime[j]*i]=1;
                if(i%prime[j]==0)
                    break;
            }
        }
    }
    
    struct son
    {
        int op,l,r;
    }ji[N];
    int an[N],kk[N];
    
    int n,m,K;
    int v[N];
    
    void work()
    {
        int order=m,flag=0;
        if(kk[m]==1)
        {
            flag=1;
            --order;
        }
        for(int i=order;i>=1;--i)
            if(kk[i]==1)
                an[i]=kk[i+1]^ji[i+1].op;
        if(flag)
        {
            int tin1,tin2,las=0;
            for(int i=1;i<m;++i)
            {
                if( kk[i]==2 )
                {
                    tin1=ji[i].l^las;
                    tin2=ji[i].r^las;
                    v[tin1]=tin2;
                }
                else
                    las=an[i];
            }
            tin1=las^ji[m].l;
            tin2=las^ji[m].r;
            sort(v+tin1,v+tin2+1);
            int con=0;
            for(int i=tin1;i<=tin2;++i)
                if(!he[v[i]])
                {
                    ++con;
                    if(con==K)
                    {
                        an[m]=v[i];
                        break;
                    }
                }
        }
    
        for(int i=1;i<=m;++i)
            if(kk[i]==1)
                printf("%d
    ",an[i]);
    }
    
    int main(){
    
        get_prime();
    
        scanf("%d%d%d",&n,&K,&m);
        for(int i=1;i<=n;++i)
            scanf("%d",&v[i]);
        for(int i=1;i<=m;++i)
            scanf("%d%d%d",&ji[i].op,&ji[i].l,&ji[i].r);
        
        int las=0;
        for(int i=1;i<=m;++i)
        {
            if( (las^ji[i].op)&1 )
            {
                kk[i]=1;
                las=1;
            }
            else
                kk[i]=2;
        }
        work();
    }
    T1

     

     

     

    T2
    n^3暴力好打

    30分,开O3 40分...

    正解就是枚举左(或上)边界,算出右边界在最右面的ans,然后再扫右边界,一个一个的去(用链表维护...)

     

     

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    #include <vector>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    const int N=3106;
    
    int tx[N],ty[N],id[N];
    int dui[N];
    int con;
    
    int R,C,n,K;
    int jix[N],jiy[N];
    ll ans,sum;
    
    int pre[N],nxt[N];
    ll v[N];
    
    bool ok(int x,int y)
    {
        /*if(tx[id[x]]==tx[id[y]])
            return ty[id[x]]<ty[id[y]];
        return tx[id[x]]<tx[id[y]];*/
        if(tx[x]==tx[y])
            return ty[x]<ty[y];
        return tx[x]<tx[y];
    }
    
    vector<int> q[N];
    
    void del(int x)
    {
        nxt[pre[x]]=nxt[x];
        pre[nxt[x]]=pre[x];
        sum-=v[x];
        int t1=nxt[x],t2=nxt[x];
        for(int i=1;i<K;++i)
            t2=nxt[t2];
        for(int i=1;i<=K;++i)
        {
            sum-=v[t1];
            v[t1]=(tx[t1]-tx[pre[t1]])*(R-tx[t2]+1);
            sum+=v[t1];
            t1=pre[t1];t2=pre[t2];
        }
    }
    
    void work()
    {
        ll temp;
        int nx;
        for(int j=1;j<=C;++j)
        {
            sum=0;con=0;mem(v,0);
    
            for(int i=1;i<=10;++i)
            {
                tx[++con]=0;
                ty[con]=0;
                tx[++con]=R+1;
                ty[con]=0;
            }
            for(int i=1;i<=n;++i)
                if(jiy[i]>=j)
                {
                    tx[++con]=jix[i];
                    ty[con]=jiy[i];
                    dui[i]=con;
                }
            for(int i=1;i<=con;++i)id[i]=i;
            sort(id+1,id+1+con,ok);
            for(int i=1;i<=con;++i)
                pre[id[i]]=id[i-1],nxt[id[i]]=id[i+1];
            pre[id[1]]=id[1];nxt[id[con]]=id[con];
            //printf("con=%d
    ",con);
            /*for(int qw=id[1],i=1;i<=con;++i,qw=nxt[qw])
                printf("%d %d
    ",tx[qw],ty[qw]);
            printf("
    ");*/
    
            for(int i=1;i<=con;++i)
            {
                nx=i;
                for(int k=1;k<K;++k)
                    nx=nxt[nx];
                //printf("%d %d %d %d
    ",tx[id[i]],ty[id[i]],tx[nx],ty[nx]);
                v[i]=(tx[i]-tx[pre[i]])*(R-tx[nx]+1);
                sum+=v[i];
                //printf("sum=%lld
    ",sum);
            }
    
            //printf("sum=%lld
    ",sum);
    
            for(int k=C;k>=j;--k)
            {
                //printf("k=%d sum=%lld
    ",k,sum);
                ans+=sum;
                temp=q[k].size();
                for(int p=0;p<temp;++p)
                    del(dui[q[k][p]]);
            }
            //printf("j=%d ans=%lld
    ",j,ans);
        }
    }
    
    int main(){
    
        //freopen("in.in","r",stdin);
        //freopen("T2.in","r",stdin);
        //freopen("T22.out","w",stdout);
    
        scanf("%d%d%d%d",&R,&C,&n,&K);
        for(int i=1;i<=n;++i)
        {
            scanf("%d%d",&jix[i],&jiy[i]);
            q[jiy[i]].push_back(i);
        }
        work();
        cout<<ans;
    }
    T2

     

    总之 这次题及其 啊啊啊啊,然后就觉得自己弱的 ...

     

  • 相关阅读:
    php2
    11-14php
    三层嵌套
    常见的浏览器兼容
    css中的一些问题及解决方法
    css
    html
    测试题
    正则表达式
    Math对象
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7616140.html
Copyright © 2020-2023  润新知