CodeChef:Magic Board(思维 & 树状数组)

All submissions for this problem are available.

Long long ago, there is a magic board. The magic board has N*N cells: N rows and Ncolumns. Every cell contains one integer, which is 0 initially. Let the rows and the columns be numbered from 1 to N.

There are 2 types of operations can be applied to the magic board:

  1. RowSet i x: it means that all integers in the cells on row i have been changed to x after this operation.
  2. ColSet i x: it means that all integers in the cells on column i have been changed to x after this operation.

And your girlfriend sometimes has an interest in the total number of the integers 0s on some row or column.

  1. RowQuery i: it means that you should answer the total number of 0s on row i.
  2. ColQuery i: it means that you should answer the total number of 0s on column i.

Input

The first line of input contains 2 space-separated integers N and Q. They indicate the size of the magic board, and the total number of operations and queries from the girlfriend.

Then each of the next Q lines contains an operation or a query by the format mentioned above.

Output

For each query, output the answer of the query.

Constraints

1 ≤ N, Q ≤ 500000 (5 * 105)
1 ≤ i ≤ N
x ∈ {0, 1} (That is, x = 0 or 1)

Sample

Input:
3 6
RowQuery 1
ColSet 1 1
RowQuery 1
ColQuery 1
RowSet 1 0
ColQuery 1

Output:
3
2
0
1

Explanation

At first, the magic board is

000 <- row 1
000
000

So the answer of first query "RowQuery 1" is 3.

After the "ColSet 1 1", the board becomes

column 1
|
V
100
100
100

So the answer of the second query "RowQuery 1" is clearly 2, since the cell (1,1)became 1. And the answer of the third query "ColQuery 1" is 0.

Finally, apply the operation "RowSet 1 0", the board has changed to

000
100
100

From this board, the answer of the last query "ColQuery 1" should be 1.

题意:Q个操作,修改操作为将一行或一列设置成x,查询操作为输出某一行或列中0的数量。

思路:加如要查询行i的0数量,先判断最后一次修改行i是什么值及时间t,如果是1,找出有几列是t之后被修改为0的,这些可以通过时间戳+Bit树完成。

# include <bits/stdc++.h>
# define mp make_pair
# define pii pair<int,int>
# define A first
# define B second
using namespace std;
const int maxn = 5e5+10;
pii c[maxn+3], r[maxn+3];
int c0[maxn+3], c1[maxn+3], r0[maxn+3], r1[maxn+3];
inline void update(int a[], int pos, int val)
{
    if(pos == 0) return;
    for(int i=pos; i<=maxn; i+=i&(-i))
        a[i] += val;
}
inline int query(int a[], int pos)
{
    if(pos == 0) return 0;
    int ans = 0;
    for(int i=pos; i; i-=i&(-i))
        ans += a[i];
    return ans;
}
int main()
{
    int n, q, x, y;
    char s[13];
    scanf("%d%d",&n,&q);
    for(int i=1; i<=q; ++i)
    {
        scanf("%s",s);
        if(s[3] == 'S')
        {
            scanf("%d%d",&x,&y);
            if(s[0] == 'R')
            {
                if(r[x].B) update(r1, r[x].A, -1);
                else update(r0, r[x].A, -1);
                if(y) update(r1, i, 1);
                else update(r0, i, 1);
                r[x] = mp(i, y);
            }
            else
            {
                if(c[x].B) update(c1, c[x].A, -1);
                else update(c0, c[x].A, -1);
                if(y) update(c1, i, 1);
                else update(c0, i, 1);
                c[x] = mp(i, y);
            }
        }
        else
        {
            scanf("%d",&x);
            int ans = 0;
            if(s[0] == 'R')
            {
                if(r[x].B) ans = query(c0, i) - query(c0, r[x].A);
                else ans = n - query(c1, i) + query(c1, r[x].A);
            }
            else
            {
                if(c[x].B) ans = query(r0, i) - query(r0, c[x].A);
                else ans = n - query(r1, i) + query(r1, c[x].A);
            }
            printf("%d\n",ans);
        }

    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值