很容易想到可以它操作序列弄成有向图,果断深搜。但我开始竟然用了一种特醇的方法,每个书架做一次深搜,复杂度O(nq),跑到57个test就不动了。看看代码吧

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std; const int MAXOPT = 100005; struct OPT{
int opt, r, c;
}op[MAXOPT]; struct bits{
char s[125];
void init(){
for(int i = 0; i < 125; i++) s[i] = 0;
}
bool find(int k){
int p = k / 8;
int m = k % 8;
if(s[p] & (1<<m)) return true;
return false;
} void set(int k){
int p = k / 8;
int m = k % 8;
s[p] |= (1<<m);
} void reset(int k){
int p = k / 8;
int m = k % 8;
s[p] ^= (1<<m);
} void flip(){
for(int i = 0; i < 125; i++){
s[i] ^= (-1);
}
}
}; struct STATE{
bits st;
void init(){
st.init();
counts = 0;
}
int counts;
}; vector<int>nt[MAXOPT]; int ans[MAXOPT];
int n, m, q; void dfs(int pos, STATE iter, int sh){
int sz = nt[pos].size();
for(int k = 0; k < sz; k++){
ans[nt[pos][k]] += iter.counts;
dfs(nt[pos][k], iter, sh);
} while(op[pos + 1].opt != 4 && pos < q){
pos ++;
if(op[pos].r == sh){
if(op[pos].opt == 1){
if(!iter.st.find(op[pos].c - 1)){
iter.counts++;
iter.st.set(op[pos].c - 1);
}
}
else if(op[pos].opt == 2){
if(iter.st.find(op[pos].c - 1)){
iter.counts --;
iter.st.reset(op[pos].c - 1);
}
}
else {
iter.st.flip();
iter.counts = m - iter.counts;
}
}
ans[pos] += iter.counts;
int sz = nt[pos].size();
for(int k = 0; k < sz; k++){
ans[nt[pos][k]] += iter.counts;
dfs(nt[pos][k], iter, sh);
}
} } int main(){
int opt, r, c;
memset(ans, 0, sizeof(ans));
scanf("%d%d%d", &n, &m, &q);
for(int i = 0; i <= q; i++)
nt[i].clear(); for(int i = 1; i <= q; i++){
scanf("%d", &op[i].opt);
if(op[i].opt == 1 || op[i].opt == 2){
scanf("%d%d", &op[i].r, &op[i].c);
}
else {
scanf("%d", &op[i].r);
}
if(op[i].opt == 4){
nt[op[i].r].push_back(i);
}
}
for(int i = 1; i <= n; i++){
STATE iter;
iter.init();
ans[0] += iter.counts;
dfs(0, iter, i);
} for(int i = 1; i <= q; i++){
printf("%d\n", ans[i]);
} return 0;
}

  

后来想到,一次操作只动一个书架,深搜之后把原来的状态还原回去就可以啦,复杂度O(q)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
//#include <bitset>
using namespace std; const int MAXOPT = 100005; int state[1005][1005]; int n, m, q; struct operation{
int op, r, c;
}op[MAXOPT];
int ans[MAXOPT];
vector<int> nt[MAXOPT]; void dfs(int u){
int sz = nt[u].size();
for(int i = 0; i < sz; i++){
int v = nt[u][i];
if(op[v].op == 1){
int pre = state[op[v].r][op[v].c];
if(!pre){
state[op[v].r][op[v].c] = 1;
ans[v] = ans[u] + 1;
}
else ans[v] = ans[u];
dfs(v);
state[op[v].r][op[v].c] = pre;
}
else if(op[v].op == 2){
int pre = state[op[v].r][op[v].c];
if(pre){
state[op[v].r][op[v].c] = 0;
ans[v] = ans[u] - 1;
}
else ans[v] = ans[u];
dfs(v);
state[op[v].r][op[v].c] = pre;
}
else if(op[v].op == 3){
int c = 0;
for(int k = 1; k <=m; k++){
if(state[op[v].r][k]) c++;
state[op[v].r][k] ^= 1;
}
ans[v] = ans[u] - c + m - c;
dfs(v); for(int k = 1; k <=m; k++){
state[op[v].r][k] ^= 1;
} }
else{
ans[v] = ans[u];
dfs(v);
}
}
} int main(){ scanf("%d%d%d", &n, &m, &q);
memset(ans, 0, sizeof(ans));
memset(state, 0, sizeof(state));
for(int i = 1; i <= q; i++){
scanf("%d", &op[i].op);
if(op[i].op == 1 || op[i].op == 2){
scanf("%d%d", &op[i].r, &op[i].c);
}
else{
scanf("%d", &op[i].r);
}
if(op[i].op == 4) nt[op[i].r].push_back(i);
else nt[i - 1].push_back(i);
} dfs(0); for(int i = 1; i <= q; i++)
printf("%d\n", ans[i]); return 0;
}

  

CF# 368 D2 D的更多相关文章

  1. CF#310 d2

    A:|c[1]-c[0]| B:A+-(oc)A[0]==0..n-1 C: #include <cstdio> int n,m,i,j,k,p; int ll,ca,cb,cc; int ...

  2. CF #368 div2

    题目链接:http://codeforces.com/contest/707/problem/A A. Brain's Photos time limit per test 2 seconds mem ...

  3. CF # 369 D2 D、E

    D,只要抓住每个点只有一个出度,那么图就能分成几个部分,而且可以发现,一个部分最多一个环. #include <iostream> #include <cstdio> #inc ...

  4. CF #330 D2 E

    相当于给你一些点,要你最多删除不超过k,使得能使用一个边长为整数的长方形,与XY轴平行,使长方形的面积最小. 上课时拿笔来画画,然后忽然思路就开了,要是比赛也这样就好了~~先按X,Y分别排序,由于K较 ...

  5. NSCharacter​Set 使用说明

    NSCharacter​Set 和 NSMutableCharacterSet  用面向对象的方式来表示一组Unicode字符,它经常与NSString及NSScanner组合起来使用,在不同的字符上 ...

  6. ssl

    在Java加密技术(八)中,我们模拟了一个基于RSA非对称加密网络的安全通信.现在我们深度了解一下现有的安全网络通信--SSL.     我们需要构建一个由CA机构签发的有效证书,这里我们使用上文中生 ...

  7. Visual Studio 2015的坑:中文字符串编译后成乱码

    (2015年8月5日更新:微软已经修复了Roslyn的这个bug,详见 https://github.com/dotnet/roslyn/pull/4303 ) 昨天,我们用VS2015编译了博客程序 ...

  8. MIM协议与Base64编码

    MIME Protocol 1. MIME的全称是"Multipurpose Internet Mail Extensions",中译为"多用途互联网邮件扩展" ...

  9. [Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】

    题目链接:CF - R296 - d2 - D 题目大意 一个特殊的图,一些数轴上的点,每个点有一个坐标 X,有一个权值 W,两点 (i, j) 之间有边当且仅当 |Xi - Xj| >= Wi ...

随机推荐

  1. 迅为嵌入式4418/6818开发板QT-HDMI显示

    本文转自迅为论坛:http://www.topeetboard.com 平台:迅为4418/6818开发平台 1.首先请确认下光盘资料的日期(只有20171120及以后更新的光盘支持QT HDMI显示 ...

  2. Day3 CSS 引入及基本选择器

    一 .CSS 层叠样式表,为了使网页元素的样式更加丰富,内容与样式拆分开来.HTML负责结构与内容,表现形式交给CSS. CSS注释/**/ 来注释 二.CSS基本语法与引用 CSS的语法结构 选择器 ...

  3. zabbix基础安装

    环境依赖:LNMP或者LAMP 简介参考:http://blog.51cto.com/zhang789/1868880 一.准备 我安装的环境及其版本如下: 系统版本 CentOS Linux rel ...

  4. 在mac下做web开发,shell常用的快捷键

    Ctrl + A 光标移动到行首 Ctrl + E 光标移动到行末 Ctrl + K 清屏(也可是用clear命令) Command +shift+{} 终端的tab左右切换

  5. 数据结构之线性顺序表ArrayList(Java实现)

    一.ListMe接口: import java.util.ArrayList; //实现线性表(顺序表和链表)的接口://提供add get isEmpty size 功能public interfa ...

  6. selenium webdriver 常用断言

    断言常用的有: assertLocation(判断当前是在正确的页面). assertTitle(检查当前页面的title是否正确). assertValue(检查input的值, checkbox或 ...

  7. 第2节 hive基本操作:11、hive当中的分桶表以及修改表删除表数据加载数据导出等

    分桶表 将数据按照指定的字段进行分成多个桶中去,说白了就是将数据按照字段进行划分,可以将数据按照字段划分到多个文件当中去 开启hive的桶表功能 set hive.enforce.bucketing= ...

  8. vs2008如何新建自己工程的环境变量(局部)和 Windows系统(全局). .

    在vs2008的Project->Property设置里经常会看到类似$(IntDir).$(OutDir).$(ProjectName) 的预定义宏.以vc2008为例,有时候我们在引用别的库 ...

  9. Java使用JNA方式调用DLL(动态链接库)(原创,装载请注明出处)

    Java使用JNA调用DLL 1.准备 1.JDK环境 2.Eclipse 3.JNA包 下载JNA包: (1).JNA的Github:https://github.com/java-native-a ...

  10. php与mysql事物处理

    PHP与MYSQL事务处理 mysql事物特性 (原子性,一致性,隔离性,持久性) /*MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事 ...