[dfs 离线] Hillan模拟赛 C.可持久化的书橱

来源:互联网 发布:老是找不到东西知乎 编辑:程序博客网 时间:2024/04/30 12:50



可以根据关系连边 形成树结构 然后dfs+回溯


#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }  return *p1++;}inline void read(int &x){  char c=nc(),b=1;  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=300005,M=1005;struct edge{  int u,v,next;}G[N];int head[N],inum;inline void add(int u,int v,int p){  G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}struct abcd{  int t,x,y,o;}W[N];int n,m;bool Map[M][M],tag[M];int num1[M],num2[M];int ans[N],cur;inline void Deal(abcd &R){  if (R.t==1 && !(Map[R.x][R.y]^tag[R.x])) Map[R.x][R.y]^=1,cur++,num1[R.x]++,num2[R.x]--,R.o=1;  if (R.t==2 && (Map[R.x][R.y]^tag[R.x])) Map[R.x][R.y]^=1,cur--,num1[R.x]--,num2[R.x]++,R.o=1;  if (R.t==3) tag[R.x]^=1,cur+=num2[R.x]-num1[R.x],swap(num1[R.x],num2[R.x]);}inline void Undeal(abcd &R){  if (R.t==1 && R.o) Map[R.x][R.y]^=1,cur--,num1[R.x]--,num2[R.x]++;  if (R.t==2 && R.o) Map[R.x][R.y]^=1,cur++,num1[R.x]++,num2[R.x]--;  if (R.t==3) tag[R.x]^=1,cur+=num2[R.x]-num1[R.x],swap(num1[R.x],num2[R.x]);}#define V G[p].vinline void dfs(int u){  Deal(W[u]);  ans[u]=cur;  for (int p=head[u];p;p=G[p].next)    dfs(V);  Undeal(W[u]);}int main(){  int Q;  freopen("bookcase.in","r",stdin);  freopen("bookcase.out","w",stdout);  read(n); read(m); read(Q);  for (int i=1;i<=Q;i++){    read(W[i].t); read(W[i].x);    if (W[i].t<=2) read(W[i].y);    if (W[i].t==4)      add(W[i].x,i,++inum);    else      add(i-1,i,++inum);  }  for (int i=1;i<=n;i++) num1[i]=0,num2[i]=m;  dfs(0);  for (int i=1;i<=Q;i++)    printf("%d\n",ans[i]);  return 0;}


0 0
原创粉丝点击