1. 程式人生 > >【CF869E】The Untended Antiquity(雜湊+二維樹狀陣列)

【CF869E】The Untended Antiquity(雜湊+二維樹狀陣列)

當覆蓋兩點的最小矩形不同時,一定不可達

這樣的問題不難想到經典的二維樹狀陣列+差分來支援二維區間覆蓋+查詢

對於覆蓋操作 我們可以差分的給這個矩陣里加上一個編號

對於操牆操作 我們可以反著減去這個編號

對於查詢 就查詢這兩個點的值是否相同 編號的累積不影響 因為只有在同一個牆內才會累積

注意 如果只是單單的把編號從1開始標號是不夠的 因為會出現1+3=2+2這類情況

需要雜湊

#include<bits/stdc++.h>
#define uint unsigned int
#define N 2505
#define lowbit(x) x&(-x)
#define base 19260817
using namespace std;
template<class T>
inline void read(T &x)
{
    x=0; int f=1;
    static char ch=getchar();
    while((!isdigit(ch))&&ch!='-')  ch=getchar();
    if(ch=='-') f=-1;
    while(isdigit(ch))  x=x*10+ch-'0',ch=getchar();
    x*=f;
}
int tree[N][N],n,m,id;
inline void add(int x,int y,int z)
{
    for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=m;j+=lowbit(j))
            tree[i][j]+=z;
}
inline int query(int x,int y)
{
    int ans=0;
    for(int i=x;i;i-=lowbit(i))
        for(int j=y;j;j-=lowbit(j))
            ans+=tree[i][j];
    return ans;
}
/*struct matrix
{
    int x1,y1,x2,y2;
    inline bool operator<(const matrix &a) const
    {
        if(x1 < a.x1)
            return 1;
        if(y1 < a.y1)
            return 1;
        if(x2 < a.x2)
            return 1;
        if(y2 < a.y2)
            return 1;
        return 0;
    }
};
map <matrix,int> M;*/
int main()
{
    int Q;
    read(n),read(m),read(Q);
    for(int i=1,x1,y1,x2,y2,opt;i<=Q;i++)
    {
        read(opt),read(x1),read(y1),read(x2),read(y2);
        uint num=x1*base*base*base+x2*base*base+y1*base+y2;
        //當覆蓋兩點的最小矩形不同時,一定不可達
        if(opt==1)
        {
        //  M[(matrix){x1,y1,x2,y2}]=++id;
            add(x1,y1,num);
            add(x1,y2+1,-num);
            add(x2+1,y1,-num);
            add(x2+1,y2+1,num);
        }
        if(opt==2)
        {
        //  int num=M[(matrix){x1,y1,x2,y2}];
            add(x1,y1,-num);
            add(x1,y2+1,num);
            add(x2+1,y1,num);
            add(x2+1,y2+1,-num);
        }
        if(opt==3)
        {
            if(query(x1,y1)==query(x2,y2)) puts("Yes");
            else puts("No");
        }
    }
    return 0;
}