Codeforces 747D Persistent Bookcase【Dfs+思维】好题!好题!

来源:互联网 发布:网络成熟男人经典语录 编辑:程序博客网 时间:2024/05/16 09:54

D. Persistent Bookcase
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

Recently in school Alina has learned what are the persistent data structures: they are data structures that always preserves the previous version of itself and access to it when it is modified.

After reaching home Alina decided to invent her own persistent data structure. Inventing didn't take long: there is a bookcase right behind her bed. Alina thinks that the bookcase is a good choice for a persistent data structure. Initially the bookcase is empty, thus there is no book at any position at any shelf.

The bookcase consists of n shelves, and each shelf has exactlym positions for books at it. Alina enumerates shelves by integers from1 to n and positions at shelves — from1 to m. Initially the bookcase is empty, thus there is no book at any position at any shelf in it.

Alina wrote down q operations, which will be consecutively applied to the bookcase. Each of the operations has one of four types:

  • 1 i j — Place a book at position j at shelfi if there is no book at it.
  • 2 i j — Remove the book from position j at shelfi if there is a book at it.
  • 3 i — Invert book placing at shelfi. This means that from every position at shelfi which has a book at it, the book should be removed, and at every position at shelfi which has not book at it, a book should be placed.
  • 4 k — Return the books in the bookcase in a state they were after applyingk-th operation. In particular, k = 0 means that the bookcase should be in initial state, thus every book in the bookcase should be removed from its position.

After applying each of operation Alina is interested in the number of books in the bookcase. Alina got 'A' in the school and had no problem finding this values. Will you do so?

Input

The first line of the input contains three integers n,m and q (1 ≤ n, m ≤ 103,1 ≤ q ≤ 105) — the bookcase dimensions and the number of operations respectively.

The next q lines describes operations in chronological order —i-th of them describes i-th operation in one of the four formats described in the statement.

It is guaranteed that shelf indices and position indices are correct, and in each of fourth-type operation the numberk corresponds to some operation before it or equals to0.

Output

For each operation, print the number of books in the bookcase after applying it in a separate line. The answers should be printed in chronological order.

Examples
Input
2 3 31 1 13 24 0
Output
140
Input
4 2 63 22 2 23 33 22 2 23 2
Output
213324
Input
2 2 23 22 2 1
Output
21
Note

This image illustrates the second sample case.


题目大意:

一共四种操作:

①1 x y 如果位子(x,y)没有书,就在上边放一本书。

②2 x y 如果位子(x,y)有书,就拿走这本书。

③ 3 x 在第x行上,如果有书,就拿走,如果没有书 ,就放一本。

④4 x 回到第x次操作结束后的状态。

问每个操作结束后,书架上共有多少本书。


思路(源自:http://blog.csdn.net/miracle_ma/article/details/52290831,很妙的解法):


1、首先我们优化修改操作,我们可以将第三种操作也变成O(1);

我们过程维护一个row【x】,表示第x行有多少本书,那么对应第三种操作对于总数量的影响为:sum=sum-row【x】+m-row【x】;

同时,对于书架的第x行,我们进行了一次翻转,那么维护一个数组fan【x】,记录第x行是否翻转过。

那么过程维护这个sum和几个数组还是很简单的。

三种操作配合亦或,总查询复杂度O(1);



2、再考虑到Dfs的特点,我们考虑用Dfs的方式来搞这个题。

首先,对于每个修改操作,对应将i-1和i连边.

如果不是修改操作(op==4),对应将回到的位子和i连边。

接下来维护Dfs过程即可。


Ac代码:

#include<stdio.h>#include<vector>#include<string.h>using namespace std;struct node{    int op,x,y;}p[100050];vector<int >mp[100005];int a[1005][1005];int fan[1005];int row[1005];int ans[100505];int n,m,q,sum;void Dfs(int pos){    int flag=0;    if(pos!=0)    {        if(p[pos].op==1)        {            if(a[p[pos].x][p[pos].y]^fan[p[pos].x]==0)            {                sum++;                a[p[pos].x][p[pos].y]^=1;                row[p[pos].x]++;                flag=1;            }        }        if(p[pos].op==2)        {            if(a[p[pos].x][p[pos].y]^fan[p[pos].x]==1)            {                sum--;                a[p[pos].x][p[pos].y]^=1;                row[p[pos].x]--;                flag=1;            }        }        if(p[pos].op==3)        {            sum-=row[p[pos].x];            sum+=m-row[p[pos].x];            fan[p[pos].x]^=1;            row[p[pos].x]=m-row[p[pos].x];            flag=1;        }        ans[pos]=sum;    }    for(int i=0;i<mp[pos].size();i++)    {        int v=mp[pos][i];        Dfs(v);    }    if(pos!=0&&flag==1)    {        if(p[pos].op==1)        {            sum--;            a[p[pos].x][p[pos].y]^=1;            row[p[pos].x]--;        }        if(p[pos].op==2)        {            sum++;            a[p[pos].x][p[pos].y]^=1;            row[p[pos].x]++;            flag=1;        }        if(p[pos].op==3)        {            sum-=row[p[pos].x];            sum+=m-row[p[pos].x];            fan[p[pos].x]^=1;            row[p[pos].x]=m-row[p[pos].x];            flag=1;        }    }}int main(){    while(~scanf("%d%d%d",&n,&m,&q))    {        for(int i=1;i<=100003;i++)mp[i].clear();        for(int i=1;i<=q;i++)        {            scanf("%d",&p[i].op);            if(p[i].op==1||p[i].op==2)scanf("%d%d",&p[i].x,&p[i].y);            else scanf("%d",&p[i].x);            if(p[i].op==4)            {                mp[p[i].x].push_back(i);            }            else            {                mp[i-1].push_back(i);            }        }        sum=0;        memset(a,0,sizeof(a));        memset(fan,0,sizeof(fan));        memset(row,0,sizeof(row));        memset(ans,0,sizeof(ans));        Dfs(0);        for(int i=1;i<=q;i++)        {            printf("%d\n",ans[i]);        }    }}












0 0
原创粉丝点击