8.5总结

8.5总结

得分

100+85+60

Rank 1~~

终于做了一次人做的比赛

T1

题目大意

给定一个n*m的矩阵,(x,y)的值为(x-1)*m+y。有k次修改操作,每次把一行或一列乘上一个系数y,求矩阵每个数的和

n,m<=1000000;k<=100000

正解

一眼题

首先,修改操作的顺序可以随便调换。

对于每一列,它的和就是(S1*m+S2*i)*yi,这个S1和S2取决于对行的修改,并且对于每一列都不变

第一行对S1的贡献是0*y1,第二行对S1的贡献是1*y2,第三行对S1的贡献是2*y3...以此类推

第一行对S2的贡献是y1,第二行对S2的贡献是y2...以此类推

T2

题目大意


正解

维护一个jump[i]数组表示第1列第i行跳m步会跳会第一列哪一行。

move的时候可以先跳到第一列,再m步m步跳找循环节

难点就在于怎么维护jump[i]数组。

我调了11个小时拿了15分

以下的"-1""+1"可能指循环意义下的增减

更新一个点(x,y)的时候,(x-1,y-1),(x,y-1)与(x+1,y-1)所能到达的第一列的节点可能发生变化,进而影响到第一列某些点的jump[i]。

由于第一列能到达点(x,y)的点一定是一个连续的区间,所以维护区间的端点就可以了。

但是有可能区间是[1~r]与[l~n],所以要特判。

把l--,r++然后往回缩。

如果l--,r++之后代表[1~n]又要特判

#include<cstdio>
#include<cstring>
#include<algorithm>
#define O3 __attribute__((optimize(3)))
using namespace std;

int n,m,Q,i,j,k,tot,ll,rr,lll,rrr,kk,rx,ry,bzz,ggg;
int x,y,z,tox,toy,xx,yy,st,en;
int a[2005][2005];
int bz[2005],l[2005];
char str[15];
int jump[2005];

O3 int read()
{
    int s=0;char ch=getchar();
    while ((ch<'0')||(ch>'9'))
    ch=getchar();
    while ((ch>='0')&&(ch<='9'))
    {
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s;
}

O3 int in(int x,int l,int r)
{
    if (x==-1) return 0;
    if (l<=r)
    {
        if ((x>=l)&&(x<=r)) return 1;
    }
    else
    {
        if ((x<=r)||(x>=l)) return 1;
    }
    return 0;
}

O3 int pre(int x)
{
    return (x+n-2)%n+1;
}

O3 int nex(int x)
{
    return x%n+1;
}

O3 int good(int x,int y)
{
    int tox,toy;
    int xx,yy;
    toy=yy=y%m+1;
    tox=x;
    xx=nex(x);
    if (a[xx][yy]>a[tox][toy])
        tox=xx;
    xx=pre(x);
    if (a[xx][yy]>a[tox][toy])
        tox=xx;
    return tox;
}

O3 void jump_to_end(int k)
{
    int tox,toy;
    while (k--)
    {
        
        toy=y%m+1;
        tox=good(x,y);
        
        x=tox;y=toy;
        if (y==1) break;
    }
}

O3 int getsum(int l,int r)
{
    if (r>=l) return r-l+1;
    else
    {
        return n-l+1+r;
    }
}

O3 void update(int xx,int yy)
{
    int ll,rr,i,lll,rrr;
    rx=x;ry=y;
    x=xx;y=yy;
    jump_to_end(m+1);
    tox=x;
    x=rx;y=ry;
    
    ll=rr=xx;
    bzz=1;
    if (yy==1)
    {
        yy=m+1;
        jump[xx]=tox;
        tox=xx;
    }
    for (i=yy-1;i>=1;i--)
    {
        lll=ll;
        rrr=rr;
        if (getsum(pre(lll),rrr)>=getsum(ll,rr)) lll=pre(lll);
        if (getsum(lll,nex(rrr))>=getsum(ll,rr)) rrr=nex(rrr);
        if (getsum(lll,rrr)==n)
        {
            if (ll<=rr)
            {
                if (ll>1)
                {
                    if (ll>2)
                    {
                        if (!in(good(3,i),ll,rr))
                        {
                            lll=3;
                            rrr=2;
                        }
                    }
                    if (!in(good(2,i),ll,rr))
                    {
                        lll=2;
                        rrr=1;
                    }
                    if (!in(good(1,i),ll,rr))
                    {
                        lll=1;
                        rrr=n;
                    }
                    if (!in(good(n,i),ll,rr))
                    {
                        lll=1;
                        rrr=n;
                    }
                }
                if (rr<n)
                {
                    if (rr<pre(n))
                    {
                        if (!in(good(pre(pre(n)),i),ll,rr))
                        {
                            lll=pre(pre(n));
                            rrr=pre(pre(pre(n)));
                        }
                    }
                    if (!in(good(pre(n),i),ll,rr))
                    {
                        lll=pre(n);
                        rrr=pre(pre(n));
                    }
                    if (!in(good(n,i),ll,rr))
                    {
                        lll=1;
                        rrr=n;
                    }
                    if (!in(good(nex(n),i),ll,rr))
                    {
                        lll=nex(n);
                        rrr=n;
                    }
                }
            }
            else
            {
                if (ll==nex(nex(rr)))
                {
                    if (!in(good(rr,i),ll,rr))
                    {
                        lll=rr;
                        rrr=pre(rr);
                    }
                    if (!in(good(nex(rr),i),ll,rr))
                    {
                        lll=nex(rr);
                        rrr=rr;
                    }
                    if (!in(good(nex(nex(rr)),i),ll,rr))
                    {
                        lll=nex(nex(rr));
                        rrr=nex(rr);
                    }
                }
                else
                {
                    if (!in(good(rr,i),ll,rr))
                    {
                        lll=rr;
                        rrr=pre(rr);
                    }
                    if (!in(good(nex(rr),i),ll,rr))
                    {
                        lll=nex(rr);
                        rrr=rr;
                    }
                    if (!in(good(nex(nex(rr)),i),ll,rr))
                    {
                        lll=nex(nex(rr));
                        rrr=nex(rr);
                    }
                    if (!in(good(nex(nex(nex(rr))),i),ll,rr))
                    {
                        lll=nex(nex(nex(rr)));
                        rrr=nex(nex(rr));
                    }
                }
            }
        }
        while ((!in(good(lll,i),ll,rr)))
        {
            lll=nex(lll);
            if (lll==nex(rrr))
            {
                bzz=0;
                break;
            }
        }
        while ((!in(good(rrr,i),ll,rr)))
        {
            rrr=pre(rrr);
            if (rrr==pre(lll))
            {
                bzz=0;
                break;
            }
        }
        if (bzz==0) break;
        ll=lll;
        rr=rrr;
        if (getsum(ll,rr)==n) break;
    }
    if (bzz==0) return;
    if (ll<=rr)
    {
        for (i=ll;i<=rr;i++)
        if ((yy!=1)||(i!=xx))
        jump[i]=tox;
    }
    else
    {
        for (i=1;i<=rr;i++)
        if ((yy!=1)||(i!=xx))
        jump[i]=tox;
        for (i=ll;i<=n;i++)
        if ((yy!=1)||(i!=xx))
        jump[i]=tox;
    }
}

O3 int main()
{
    freopen("read.in","r",stdin);
    freopen("jump.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++)
    {
        for (j=1;j<=m;j++)
        {
            a[i][j]=read();
        }
    }
    for (i=1;i<=n;i++)
    {
        x=i; y=1;
        jump_to_end(m+1);
        jump[i]=x;
    }
    x=1;y=1;
    scanf("%d",&Q);
    while (Q--)
    {
        
        scanf("%s",str+1);
        if (str[1]=='m')
        {
            scanf("%d",&k);
            kk=k-(m-y+1);
            jump_to_end(k);
            k=kk;
            if (k<=0)
            {
                printf("%d %d\n",x,y);
                continue;
            }
            memset(bz,0,sizeof(bz));
            tot=1;
            l[1]=x;
            bz[x]=1;
            while (k>=m)
            {
                if (bz[jump[x]]==0)
                {
                    bz[jump[x]]=bz[x]+1;
                    l[++tot]=jump[x];
                    x=jump[x];
                    k-=m;
                }
                else
                {
                    en=bz[x];
                    st=bz[jump[x]];
                    k-=m;
                    break;
                }
            }
            
            if (k>=m)
            {
                x=l[st+(k/m)%(en-st+1)];
                k=k%m;
            }
            jump_to_end(k);
            printf("%d %d\n",x,y);
        }
        else
        {
            scanf("%d%d%d",&xx,&yy,&z);
            a[xx][yy]=z;
            update(xx,(yy-2+m)%m+1);
            update(pre(xx),(yy-2+m)%m+1);
            update(nex(xx),(yy-2+m)%m+1);
        }
    }
}

小结

  1. 每道题都一定要做,都要拿分,多看数据的特殊性质。
  2. 时间安排要合理,有计划性

猜你喜欢

转载自www.cnblogs.com/leason-lyx/p/11306813.html
8.5