题目传送门: http://codeforces.com/contest/707/problem/D
题意: 有一个书架,书架有n层,每层有m个位置,接下来是q组操作,操作有四种方式,输出每次操作后书架中书的数量
四种操作:
- 1 i j — Place a book at position j at shelf i if there is no book at it.
- 2 i j — Remove the book from position j at shelf i if there is a book at it.
- 3 i — Invert book placing at shelf i. This means that from every position at shelf i which has a book at it, the book should be removed, and at every position at shelf i 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 applying k-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.
思路:离线建一个查询树即可
代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <bitset>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long
#define ull unsigned long long
#define mem(n,v) memset(n,v,sizeof(n))
#define MAX 100005
#define MAXN 200005
#define PI 3.1415926
#define E 2.718281828459
#define opnin freopen("text.in.txt","r",stdin)
#define opnout freopen("text.out.txt","w",stdout)
#define clsin fclose(stdin)
#define clsout fclose(stdout)
#define haha1 cout << "haha1"<< endl
#define haha2 cout << "haha2"<< endl
#define haha3 cout << "haha3"<< endl
const int INF = 0x3f3f3f3f;
const ll INFF = 0x3f3f3f3f3f3f3f3f;
const double pi = 3.141592653589793;
const double inf = 1e18;
const double eps = 1e-8;
const ll mod = 1e9+7;
const ull mx = 133333331;
/**************************************************************************/
bitset <1005> book[1005];
int n,m,q;
int head[MAX];
int cnt;
int num;
struct edge
{
int val,to,next;
int x,y;
edge(int v = 0,int t = 0,int n = -1,int a = 0,int b = 0) : val(v),to(t),next(n),x(a),y(b) {}
}edges[MAXN];
int ans[MAX];
int vis[MAX];
void init()
{
mem(vis,0);
mem(book,0);
mem(ans,0);
mem(head,-1);
mem(edges,0);
cnt = 0;
num = 0;
}
void addedge(int u,int v,int val,int x,int y)
{
edges[cnt].to = v;
edges[cnt].val = val;
edges[cnt].next = head[u];
edges[cnt].x = x;
edges[cnt].y = y;
head[u] = cnt++;
}
void dfs(int u)
{
vis[u] = 1;
for(int i=head[u];i != -1;i = edges[i].next){
int t = edges[i].to;
int v = edges[i].val;
int x = edges[i].x;
int y = edges[i].y;
if(v == 1){
if(!book[x][y]){
num++;
book[x][y] = 1;
ans[t] = num;
if(!vis[t]) dfs(t);
book[x][y] = 0;
num--;
}
else{
ans[t] = num;
if(!vis[t]) dfs(t);
}
}
else if(v == 2){
if(book[x][y]){
num--;
book[x][y] = 0;
ans[t] = num;
if(!vis[t]) dfs(t);
book[x][y] = 1;
num++;
}
else{
ans[t] = num;
if(!vis[t]) dfs(t);
}
}
else if(v == 3){
for(int i=1;i<=m;i++){
if(!book[x][i]) num++;
else num--;
book[x][i] = 1 - book[x][i];
}
ans[t] = num;
if(!vis[t]) dfs(t);
for(int i=1;i<=m;i++){
if(!book[x][i]) num++;
else num--;
book[x][i] = 1 - book[x][i];
}
}
else{
ans[t] = num;
if(!vis[t]) dfs(t);
}
}
}
int main()
{
init();
cin >> n >> m >> q;
int id = 0;
for(int i=1;i<=q;i++){
int val = 0,x = 0,y = 0;
scanf("%d",&val);
if(val == 1 || val == 2) scanf("%d %d",&x,&y);
else scanf("%d",&x);
if(val == 4) id = x;
addedge(id,i,val,x,y);
if(val != 4) id = i;
}
dfs(0);
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
}