• [JOI2012春季合宿]Rotate (链表)


    题意

    题解

    又是一道神仙题……
    显然的做法是大力splay,时间复杂度(O((N+Q)Nlog N)), 可以卡掉。
    正解: 使用十字链表维护矩阵,在周围增加第(0)行/列和第((n+1))行/列,设(li[x][d])表示(x)这个点在(d)这个方向上的下一个元素的编号是什么(一开始给每个元素都编上号)。那么对于一次旋转,子矩形边界上的格子暴力修改,内部相当于把(4)个方向做了个轮换,因此可以打标记实现。
    然而本题的实现方法比较神奇: 每次修改从((0,0))走到((x,y)) (只花费(O(N))的时间),首先((0,0))的标记一定是正确的(因为没有修改过),然后一路上通过当前点和下一个点互相储存位置的偏移量以及当前点的正确标记确定下一个点的正确标记。(详见代码,我的代码里标记的含义是实际方向等于存储方向加标记)
    时间复杂度(O((N+Q)N)).

    代码

    #include<bits/stdc++.h>
    #define llong long long
    using namespace std;
     
    const int N = 1002;
    const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    char ch[N+3];
    char a[N*N+3];
    int li[N*N+3][4];
    int tag[N*N+3];
    int aux1[4][N+3],aux2[4][N+3];
    int n,q;
     
    int getid(int x,int y) {return x*(n+2)+y+1;}
    int getnxt(int u,int dir)
    {
        int ret = li[u][(dir-tag[u]+4)&3];
        for(int i=0; i<4; i++) {if(li[ret][i]==u) {tag[ret] = (dir-i+6)&3;}}
        return ret;
    }
     
    int main()
    {
        scanf("%d%d",&n,&q);
        for(int i=1; i<=n; i++) {scanf("%s",ch+1); for(int j=1; j<=n; j++) a[getid(i,j)] = ch[j];}
        for(int i=0; i<=n+1; i++)
        {
            for(int j=0; j<=n+1; j++)
            {
                int u = getid(i,j);
                for(int k=0; k<4; k++)
                {
                    if(i+dx[k]>=0&&i+dx[k]<=n+1&&j+dy[k]>=0&&j+dy[k]<=n+1) {li[u][k] = getid(i+dx[k],j+dy[k]);}
                }
            }
        }
        while(q--)
        {
            int x,y,l; scanf("%d%d%d",&x,&y,&l);
            int u = 1;
            for(int i=0; i<x; i++) u = getnxt(u,0);
            for(int i=0; i<y; i++) u = getnxt(u,1);
            for(int k=0; k<4; k++)
            {
                for(int i=0; i<l; i++)
                {
                    aux1[k][i] = u; aux2[k][i] = getnxt(u,(k+3)&3);
                    if(i<l-1) u = getnxt(u,k);
                }
            }
            for(int k=0; k<4; k++)
            {
                for(int i=0; i<l; i++)
                {
                    li[aux1[k][i]][(k-tag[aux1[k][i]]+3)&3] = aux2[(k+1)&3][i];
                    li[aux2[k][i]][(k-tag[aux2[k][i]]+5)&3] = aux1[(k+3)&3][i];
                }
            }
        }
        int u = 1;
        for(int i=1; i<=n; i++)
        {
            u = getnxt(u,0);
            int uu = u;
            for(int j=1; j<=n; j++) {uu = getnxt(uu,1); ch[j] = a[uu];/* printf("%d ",uu);*/}
            puts(ch+1);
    //      puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    XSS--PHPwind5.3复现
    网络基础一
    不老的神器--namp,awvs
    苏醒的巨人----CSRF
    XSS--编码绕过,qcms,鲶鱼cms
    XSS----payload,绕过,xss小游戏记录
    sql注入--高权限,load_file读写文件
    提权基础-----mysql-udf提权
    weblogic AND jboss 反序列化漏洞
    简单的压力测试工具 siege
  • 原文地址:https://www.cnblogs.com/suncongbo/p/11723879.html
Copyright © 2020-2023  润新知