Codeforces Round #791 (Div. 2) C. Rooks Defenders(树状数组)

https://codeforces.com/contest/1679/problem/C

您有一个大小为n×n的正方形棋盘。行从上到下编号为1到n,列从左到右编号为1到n。因此,每个单元格用一对整数(x,y) (1≤x,y≤n)表示,其中x是行号,y是列号。

您必须执行三种类型的q查询:

在单元格(x,y)中放一辆新车。
从单元格(x,y)中移除一辆车。可以保证车以前被放在这个棋盘里。
检查棋盘的子矩形(x1,y1)(x2,y2)的每个格子是否受到至少一辆车的攻击。
Subrectangle是一组单元格(x,y ),每个单元格满足两个条件:x1≤x≤x2,y1≤y≤y2。

回想一下,如果a=c或b=d,单元格(a,b)受到放置在单元格(c,d)中的车的攻击。特别是,包含车的单元格受到该车的攻击。

投入
第一行包含两个整数n和q (1≤n≤10^5,1≤q≤2⋅10^5) —分别是棋盘的大小和查询的次数。

以下q行中的每一行都包含一个查询的描述。描述以整数t (t∈{1,2,3})开始,表示查询的类型:

如果t=1,则接下来是两个整数x和y(1≤x,y≤n) —新车应该放入的单元格的坐标。保证在给定的查询时刻,单元格(x,y)中没有车。
如果t=2,则接下来是两个整数x和y(1≤x,y≤n) —要从中移除车的像元的坐标。在给定的查询时刻,保证在单元格(x,y)中有一辆车。
如果t=3,则接下来是四个整数x1、y1、x2和y2(1≤x1≤x2≤n,1≤y1≤y2≤n) — subrectangle,以检查其中的每个单元是否受到至少一辆车的攻击。
保证在q个查询中至少有一个第三种类型的查询。

输出
在单独一行中打印第三种类型的每个查询的答案。如果子矩形的每个格子至少被一辆车攻击,打印“Yes”(不带引号)。

否则打印“No”(不带引号)。
input
8 10
1 2 4
3 6 2 7 2
1 3 2
3 6 2 7 2
1 4 3
3 2 6 4 8
2 4 3
3 2 6 4 8
1 4 8
3 2 6 4 8
output
No
Yes
Yes
No
Yes

树状数组板子题,但是这个题目因为涉及到行和列,所以就需要开两个树,往板子里多加入一个参数即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=200200;
int n,q;
int r[N],c[N];//行r 列c
int tx[N],ty[N];//tr[N]
int lowbit(int x)
{
    return x&-x;
}
void add(int tr[],int x,int v)//为什么要加第一个东西?这是因为有行有列,它其实是有两棵树
{
    for(int i=x;i<=n;i+=lowbit(i))
        tr[i]+=v;
}
int query(int tr[],int x)
{
    int res=0;
    for(int i=x;i>=1;i-=lowbit(i))
        res+=tr[i];
    return res;
}
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(0);
    cin>>n>>q;
    int op,x1,y1,x2,y2;
    while(q--)
    {
        cin>>op;
        if(op==1)
        {
            cin>>x1>>y1;
            r[x1]++; //x1这行加一辆车
            c[y1]++; //y1这列加一辆车
            if(r[x1]==1) add(tx,x1,1);
            if(c[y1]==1) add(ty,y1,1);
        }
        else if(op==2)
        {
            cin>>x1>>y1;
            r[x1]--; //x1这行删掉一辆车
            c[y1]--; //y1这列删掉一辆车
            if(r[x1]==0) add(tx,x1,-1);
            if(c[y1]==0) add(ty,y1,-1);
        }
        else if(op==3)
        {
            cin>>x1>>y1>>x2>>y2;
            //只要横的每一行都有或者是属的每一列都有车,那么就可以
            if(query(tx,x2)-query(tx,x1-1)==(x2-x1+1)||query(ty,y2)-query(ty,y1-1)==(y2-y1+1))
                cout<<"Yes"<<endl;
            else
                cout<<"No"<<endl;
        }
    }
    return 0;
}
posted @ 2022-08-09 10:46  Vijurria  阅读(33)  评论(0编辑  收藏  举报