CF232E Quick Tortoise , Fzoj 3118

Posted algebra-hy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF232E Quick Tortoise , Fzoj 3118相关的知识,希望对你有一定的参考价值。

这一题由于数据较多,我们考虑离线处理。

分治。对于两个点s,t,如果起点在mid这条横线上方,终点在下方,那么它必定会穿过mid这条线。所以只要s可以到mid上一点x,x可以到t,st就是安全的。

用bitset维护。设\(f1[i][j]\)为上方ij到mid这条线的是否可以的01值,\(f2[i][j]\)为下方ij到mid的01值。将f1[sx][sy]&f2[tx][ty],如果结果存在1,那么就能走到。

Codeforces版本

#include <cstdio>
#include <bitset>
#include <string>
#include <algorithm>
using namespace std;
const int S=505,N=600003;
int n,m,Q,fr[S],ed[S];
char a[S][S];
bitset<500> f[S][S],g[S][S],h;
bool res[N];
struct info

    int x,y,X,Y,i;
w[N];
void divdo(int l,int r)

    if (l>r) return;
    int mid=(l+r)>>1;
    for (int i=m;i>=1;i--)
    
        if (a[mid][i]=='0')
        
            f[mid][i]=f[mid][i+1];
            f[mid][i][i]=1;
        
        else f[mid][i].reset();
    
    for (int i=mid-1;i>=l;i--)
        for (int j=m;j>=1;j--)
        
            f[i][j].reset();
            if (a[i][j]=='0')
            
                if (a[i+1][j]=='0')
                    f[i][j]|=f[i+1][j];
                if (a[i][j+1]=='0')
                    f[i][j]|=f[i][j+1];
            
        
        

    for (int i=1;i<=m;i++)
    
        if (a[mid][i]=='0')
        
            g[mid][i]=g[mid][i-1];
            g[mid][i][i]=1;
        
        else g[mid][i].reset();
    
    for (int i=mid+1;i<=r;i++)
        for (int j=1;j<=m;j++)
        
            g[i][j].reset();
            if (a[i][j]=='0')
            
                if (a[i-1][j]=='0')
                    g[i][j]|=g[i-1][j];
                if (a[i][j-1]=='0')
                    g[i][j]|=g[i][j-1];
            
        
    for (int i=fr[l];i<=ed[mid];i++)
    
        if (mid<=w[i].X && w[i].X<=r)
        
            h=f[w[i].x][w[i].y]&g[w[i].X][w[i].Y];
            if (h.any())
                res[w[i].i]=true;
        
    
    divdo(l,mid-1);
    divdo(mid+1,r);

void read(int &s)

    s=0;char c=getchar();
    while (c<'0' || c>'9') c=getchar();
    while (c>='0' && c<='9') s=(s<<1)+(s<<3)+(c^48),c=getchar();

inline bool cmp(const info &a,const info &b)

    return a.x<b.x;

int main()

    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        scanf("%s",a[i]+1);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            if (a[i][j]=='.')
                a[i][j]='0';
            else a[i][j]='1';
    scanf("%d",&Q);
    for (int i=1;i<=Q;i++)
    
        read(w[i].x);
        read(w[i].y);
        read(w[i].X);
        read(w[i].Y);
        w[i].i=i;
    
    sort(w+1,w+1+Q,cmp);
    int ii=1;
    for (int i=1;i<=n;i++)
    
        while (ii<=Q && w[ii].x<=i)
            ii++;
        ed[i]=ii-1;
    
    ii=Q;
    for (int i=n;i>=1;i--)
    
        while (ii>=1 && w[ii].x>=i)
            ii--;
        fr[i]=ii+1;
    
    divdo(1,n);
    for (int i=1;i<=Q;i++)
        if (res[i]) puts("Yes");
        else puts("No");
    return 0;

Fzoj版本

#include <cstdio>
#include <bitset>
#include <string>
#include <algorithm>
using namespace std;
const int S=505,N=600003;
int n,m,Q,fr[S],ed[S];
char a[S][S];
bitset<500> f[S][S],g[S][S],h;
bool res[N];
struct info

    int x,y,X,Y,i;
w[N];
void divdo(int l,int r)

    if (l>r) return;
    int mid=(l+r)>>1;
    for (int i=m;i>=1;i--)
    
        if (a[mid][i]=='0')
        
            f[mid][i]=f[mid][i+1];
            f[mid][i][i]=1;
        
        else f[mid][i].reset();
    
    for (int i=mid-1;i>=l;i--)
        for (int j=m;j>=1;j--)
        
            f[i][j].reset();
            if (a[i][j]=='0')
            
                if (a[i+1][j]=='0')
                    f[i][j]|=f[i+1][j];
                if (a[i][j+1]=='0')
                    f[i][j]|=f[i][j+1];
            
        
        

    for (int i=1;i<=m;i++)
    
        if (a[mid][i]=='0')
        
            g[mid][i]=g[mid][i-1];
            g[mid][i][i]=1;
        
        else g[mid][i].reset();
    
    for (int i=mid+1;i<=r;i++)
        for (int j=1;j<=m;j++)
        
            g[i][j].reset();
            if (a[i][j]=='0')
            
                if (a[i-1][j]=='0')
                    g[i][j]|=g[i-1][j];
                if (a[i][j-1]=='0')
                    g[i][j]|=g[i][j-1];
            
        
    for (int i=fr[l];i<=ed[mid];i++)
    
        if (l<=w[i].x && w[i].x<=mid && mid<=w[i].X && w[i].X<=r)
        
            h=f[w[i].x][w[i].y]&g[w[i].X][w[i].Y];
            if (h.any())
                res[w[i].i]=true;
        
    
    divdo(l,mid-1);
    divdo(mid+1,r);

void read(int &s)

    s=0;char c=getchar();
    while (c<'0' || c>'9') c=getchar();
    while (c>='0' && c<='9') s=(s<<1)+(s<<3)+(c^48),c=getchar();

inline bool cmp(const info &a,const info &b)

    return a.x<b.x;

int main()

    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        scanf("%s",a[i]+1);
    scanf("%d",&Q);
    for (int i=1;i<=Q;i++)
    
        read(w[i].x);
        read(w[i].y);
        read(w[i].X);
        read(w[i].Y);
        w[i].i=i;
    
    sort(w+1,w+1+Q,cmp);
    int ii=1;
    for (int i=1;i<=n;i++)
    
        while (ii<=Q && w[ii].x<=i)
            ii++;
        ed[i]=ii-1;
    
    ii=Q;
    for (int i=n;i>=1;i--)
    
        while (ii>=1 && w[ii].x>=i)
            ii--;
        fr[i]=ii+1;
    
    divdo(1,n);
    for (int i=1;i<=Q;i++)
        if (res[i]) puts("Safe");
        else puts("Dangerous");
    return 0;

以上是关于CF232E Quick Tortoise , Fzoj 3118的主要内容,如果未能解决你的问题,请参考以下文章

cf232E. Quick Tortoise(分治 bitset dp)

CodeForces 232E.Quick Tortoise

在中间使用Tortoise-Hg abort进行克隆[命令返回代码255]

2076 Problem F Quick Brown Fox

tortoise SVN强制用户写日志的钩子脚本

Tortoise 1.9:Merge 不记录 mergeinfo