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\n",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\n",con);
        /*for(int qw=id[1],i=1;i<=con;++i,qw=nxt[qw])
            printf("%d %d\n",tx[qw],ty[qw]);
        printf("\n");*/

        for(int i=1;i<=con;++i)
        {
            nx=i;
            for(int k=1;k<K;++k)
                nx=nxt[nx];
            //printf("%d %d %d %d\n",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\n",sum);
        }

        //printf("sum=%lld\n",sum);

        for(int k=C;k>=j;--k)
        {
            //printf("k=%d sum=%lld\n",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\n",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

 

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

 

posted @ 2017-09-30 21:03  A_LEAF  阅读(160)  评论(0编辑  收藏  举报