test20181005 迷宫

题意


分析


时间复杂度里的n,m写反了。
出题人很有举一反三的精神。

代码

我的代码常数巨大,加了各种优化后开O3最慢点都要0.9s。

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#define rg register
#define il inline
#pragma GCC optimize ("O0")
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    rg char ch=nc();rg int sum=0;
    while(!(ch>='0'&&ch<='9'))ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return sum;
}
typedef long long ll;
const int INF=0x3f3f3f3f;

const int MAXN=2e5+7;
int n,m;
int maze[6][MAXN];

struct node
{
    int dis[6][6];
    
    il node()
    {
        memset(dis,0x3f,sizeof dis);
    }
    
    il int*operator[](rg const int&x)
    {
        return dis[x];
    }
    
    il node operator+(rg const node&rhs)const
    {
        rg node res;
        for(rg int i=1;i<=n;++i)
            for(rg int j=1;j<=n;++j)
                for(rg int k=1;k<=n;++k)
                    res[i][j]=min(res[i][j],dis[i][k]+rhs.dis[k][j]+1);
        return res;
    }
};

int ql,qr;
struct SegTree
{
    node data[MAXN<<2];
    int L[MAXN<<2],R[MAXN<<2];
#define lson (now<<1)
#define rson (now<<1|1)
    il void build(rg int now,rg int l,rg int r)
    {
        L[now]=l,R[now]=r;
        if(l==r)
        {
            for(rg int i=1;i<=n;++i)
                for(rg int j=i;j<=n;++j)
                {
                    if(maze[j][l])
                        data[now][i][j]=data[now][j][i]=j-i;
                    else
                        break;
                }
            return;
        }
        rg int mid=(l+r)>>1;
        build(lson,l,mid);
        build(rson,mid+1,r);
        data[now]=data[lson]+data[rson];
    }
    
    il void change(rg int now)
    {
        if(L[now]==R[now])
        {
            memset(data[now].dis,0x3f,sizeof data[now].dis);
            for(rg int i=1;i<=n;++i)
                for(rg int j=i;j<=n;++j)
                {
                    if(maze[j][L[now]])
                        data[now][i][j]=data[now][j][i]=j-i;
                    else
                        break;
                }
            return;
        }
        rg int mid=(L[now]+R[now])>>1;
        if(ql<=mid)
            change(lson);
        else
            change(rson);
        data[now]=data[lson]+data[rson];
    }
    
    il node qmin(rg int now)
    {
        if(ql<=L[now]&&R[now]<=qr)
            return data[now];
        rg int mid=(L[now]+R[now])>>1;
        if(qr<=mid)
            return qmin(lson);
        if(ql>=mid+1)
            return qmin(rson);
        return qmin(lson)+qmin(rson);
    }
}T;

int main()
{
  freopen("maze.in","r",stdin);
  freopen("maze.out","w",stdout);
    int q;
    n=read(),m=read(),q=read();
    for(rg int i=1;i<=n;++i)
        for(rg int j=1;j<=m;++j)
            maze[i][j]=read();
    T.build(1,1,m);
    while(q--)
    {
        static int opt,a,b,c,d;
        opt=read();
        if(opt==1)
        {
            a=read(),b=read();
            maze[a][b]^=1;
            ql=b;
            T.change(1);
        }
        else
        {
            a=read(),b=read(),c=read(),d=read();
            ql=b,qr=d;
            rg int x=T.qmin(1)[a][c];
            printf("%d\n",x<INF?x:-1);
        }
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

std的写法很优,不开O3都能0.9s。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define rg register
#define N 1<<19
#define INF 0x3f3f3f3f
char ch;void re(rg int& x)
{
    while(ch=getchar(),ch<'!');x=ch-48;
    while(ch=getchar(),ch>'!')x=x*10+ch-48;
}
using namespace std;
int n,m,q,l[N],r[N],p[6][N];
struct node
{
    int dis[6][6];
    node(){memset(dis,INF,sizeof dis);}
    node operator + (const node& a)const
    {
        rg node tmp;
        for(rg int i=1;i<=n;++i)
            for(rg int j=1;j<=n;++j)
                for(rg int k=1;k<=n;++k)
                    tmp.dis[i][j]=min(tmp.dis[i][j],dis[i][k]+a.dis[k][j]+1);
        return tmp;
    }
}data[N];
void build(rg int k,rg int a,rg int b)
{
    l[k]=a,r[k]=b;
    if(a == b)
    {
        for(rg int i=1;i<=n;++i)
            for(rg int j=i;j<=n;++j)
                if(p[j][a])
                    data[k].dis[i][j]=data[k].dis[j][i]=j-i;
                else break;
        return;
    }
    build(k<<1,a,a+b>>1);
    build(k<<1|1,(a+b>>1)+1,b);
    data[k]=data[k<<1]+data[k<<1|1];
}
void change(rg int k,rg int a)
{
    if(l[k] == r[k])
    {
        memset(data[k].dis,INF,sizeof data[k].dis);
        for(rg int i=1;i<=n;++i)
            for(rg int j=i;j<=n;++j)
                if(p[j][a])
                    data[k].dis[i][j]=data[k].dis[j][i]=j-i;
                else break; 
        return; 
    }
    if(a <= l[k]+r[k]>>1)change(k<<1,a);
    else change(k<<1|1,a);
    data[k]=data[k<<1]+data[k<<1|1];    
}
node solve(rg int k,rg int a,rg int b)
{
    if(a<=l[k] && b>=r[k])return data[k];
    rg int mid=l[k]+r[k]>>1;
    if(b<=mid)return solve(k<<1,a,b);
    else if(a>mid)return solve(k<<1|1,a,b);
    else return solve(k<<1,a,b)+solve(k<<1|1,a,b);
}
int main()
{
    freopen("maze.in","r",stdin);
    freopen("maze.out","w",stdout);
    re(n),re(m),re(q);
    for(rg int i=1;i<=n;++i)
        for(rg int j=1;j<=m;++j)    
            re(p[i][j]);
    build(1,1,m);
    rg int opt,a,b,c,d;
    while(q--)
    {
        re(opt),re(a),re(b);
        if(opt == 1)
            p[a][b]^=1,change(1,b);
        else 
        {
            re(c),re(d);
            rg int x=solve(1,b,d).dis[a][c];
            printf("%d\n",x<INF?x:-1);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/9746078.html
今日推荐