Jzoj4838 I like Matrix!
2017-10-30 21:46
274 查看
(I DO NOT like matrix!!!)
首先我们可以暴力 O(nmq)
考虑压位(bitset)可以得到60pts
正解:我们发现,这些操作如果用边连接起来会形成一颗树(每个节点必然入度为1)
那我们考虑用离线方法,将所有的操作连接起来,dfs遍历整颗操作树,每个操作都暴力修改&还原
这样最多就是O(nq)的
(然而我并不认为O(nq)能过,因为n<=1000 q<=100000,可能数据第一个操作比较多吧)
#include<stdio.h> #include<string.h> #define N 100010 struct E{ int v,nt; } G ; int h ,op [3],ans ,n,m,q,c=0,S=0; bool s[1010][1010]; inline void adj(int x,int y){ G[++c]=(E){y,h[x]}; h[x]=c; } void mak(int x,int o,int i,int j){ if(o==1){ S+=(s[i][j]?-1:1); s[i][j]^=1; } if(o==2){ for(j=1;j<=m;++j) S+=(s[i][j]?-1:1),s[i][j]^=1; } if(o==3){ for(j=1;j<=n;++j) S+=(s[j][i]?-1:1),s[j][i]^=1; } } void dijk(int x){ if(x) mak(x,op[x][0],op[x][1],op[x][2]); if(x) ans[x]=S; for(int i=h[x];i;i=G[i].nt) dijk(G[i].v); if(x) mak(x,op[x][0],op[x][1],op[x][2]); } int main(){ freopen("present.in","r",stdin); freopen("present.out","w",stdout); scanf("%d%d%d",&n,&m,&q); for(int x,y,i=1;i<=q;++i){ scanf("%d%d",&x,&y); if(x==1){ x=y; scanf("%d",&y); op[i][0]=1; op[i][1]=x; op[i][2]=y; adj(i-1,i); } else if(x==2){ op[i][0]=2; op[i][1]=y; adj(i-1,i); } else if(x==3){ op[i][0]=3; op[i][1]=y; adj(i-1,i); } else { adj(y,i); } } dijk(0); for(int i=1;i<=q;++i) printf("%d\n",ans[i]); }
相关文章推荐
- [JZOJ4838]I Like Matrix!
- 【JZOJ5434】【NOIP2017提高A组集训10.30】Matrix
- JZOJ.4709【NOIP2016提高A组模拟8.17】Matrix
- 2017年11月01日普及组 I Like Matrix!
- 【JZOJ 4709】 Matrix
- JZOJ 5434. 【NOIP2017提高A组集训10.30】Matrix
- JZOJ5434. 【NOIP2017提高A组集训10.30】Matrix
- jzoj P1665 【coci2011/2012 1】MATRIX
- JZOJ 5434. 【NOIP2017提高A组集训10.30】Matrix
- I Like Matrix!
- 【JZOJ 4709】Matrix
- [JZOJ4837]I Liked Matrix!
- SSP P2821 I Like Matrix!
- 【JZOJ 5434】【NOIP2017提高A组集训10.30】Matrix
- JZOJ__Day 1【NOIP普及模拟】MATRIX
- JZOJ 4709 Matrix【NOIP2016提高A组模拟8.17】
- [JZOJ4709] Matrix
- [jzoj]1228. Matrix(贪心的最优性证明)
- leetcode Set Matrix Zeroes