hdu 5068 Harry And Math Teacher 线段树

来源:互联网 发布:mysql 日期截断 编辑:程序博客网 时间:2024/06/06 03:10

今天状态不错把这题A了,那天打BC的时候看错题了= =

题意:有n层楼,每层楼有两个门,每个门都通过两个楼梯和下一层的两个门相连,m次操作,把某条楼梯的状态改变(可用与不可用),或者询问从一层到另一层有多少种走法,需要注意的就是如果你从x-1层走到了x层的a门,那么你只能从a门再走到下一层。当时就死在这了。。

一个线段树t[x][md],md表示四种从l层走到r层的进与出的四种搭配(0-0,0-1,1-0,1-1),建树、更新的时候都是分别更新这四个值,查询的时候返回一个结构,里面存的是这四个值x1,x2,x3,x4,如果L和R在左右子树都有一部分的话就用返回的两个结构相乘得到答案。

#define _CRT_SECURE_NO_WARNINGS#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define mod 1000000007#define lson l,m,x<<1#define rson m,r,x<<1|1#define LL __int64int n;LL t[200005][4];int dir[4][2]={0,0,0,1,1,0,1,1};typedef struct aa{LL x1,x2,x3,x4;aa(){};aa(LL a,LL b,LL c,LL d){x1=a;x2=b;x3=c;x4=d;}} Ans;void es_tree(int l,int r,int x){if(r==l+1){t[x][0]=t[x][1]=t[x][2]=t[x][3]=1;return;}int m=(l+r)/2;es_tree(lson);es_tree(rson);t[x][0]=t[x<<1][0]*t[x<<1|1][0]+t[x<<1][1]*t[x<<1|1][2];t[x][1]=t[x<<1][0]*t[x<<1|1][1]+t[x<<1][1]*t[x<<1|1][3];t[x][2]=t[x<<1][2]*t[x<<1|1][0]+t[x<<1][3]*t[x<<1|1][2];t[x][3]=t[x<<1][2]*t[x<<1|1][1]+t[x<<1][3]*t[x<<1|1][3];t[x][0]%=mod;t[x][1]%=mod;t[x][2]%=mod;t[x][3]%=mod;}void update(int L,int mode,int l,int r,int x){if(l==L&&r==L+1){t[x][mode]^=1;return;}int m=(l+r)/2;if(L<m) update(L,mode,lson);else update(L,mode,rson);t[x][0]=t[x<<1][0]*t[x<<1|1][0]+t[x<<1][1]*t[x<<1|1][2];t[x][1]=t[x<<1][0]*t[x<<1|1][1]+t[x<<1][1]*t[x<<1|1][3];t[x][2]=t[x<<1][2]*t[x<<1|1][0]+t[x<<1][3]*t[x<<1|1][2];t[x][3]=t[x<<1][2]*t[x<<1|1][1]+t[x<<1][3]*t[x<<1|1][3];t[x][0]%=mod;t[x][1]%=mod;t[x][2]%=mod;t[x][3]%=mod;}Ans query(int L,int R,int l,int r,int x){if(L==l&&R==r){return Ans(t[x][0],t[x][1],t[x][2],t[x][3]);}int m=(l+r)/2;if(R<=m) return query(L,R,lson);if(L>=m) return query(L,R,rson);Ans a=query(L,m,lson),b=query(m,R,rson);return Ans((a.x1*b.x1+a.x2*b.x3)%mod,(a.x1*b.x2+a.x2*b.x4)%mod,(a.x3*b.x1+a.x4*b.x3)%mod,(a.x3*b.x2+a.x4*b.x4)%mod);}int select(int from,int to){for(int i=0;i<=3;i++) if(from==dir[i][0]&&to==dir[i][1]) return i;}int main(){int md,x,f,to,a,m;while(scanf("%d%d",&n,&m)!=EOF){memset(t,0,sizeof(t));es_tree(1,n,1);while(m--){scanf("%d",&md);if(md){scanf("%d%d%d",&x,&f,&to);int a=select(f-1,to-1);update(x,a,1,n,1);}else{scanf("%d%d",&f,&to);Ans ret=query(f,to,1,n,1);printf("%I64d\n",(ret.x1+ret.x2+ret.x3+ret.x4)%mod);}}}return 0;}

0 0
原创粉丝点击