hdu 5068
来源:互联网 发布:一个人根本做不起淘宝 编辑:程序博客网 时间:2024/06/05 15:35
一道好题~
用矩阵代替DP方程。
对于每个房间构造一个矩阵mat,mat[i][j] = 1 或 0 表示
然后线段树每个结点维护区间区间矩阵乘法的结果
对于询问操作用矩阵乘法合并区间即可。
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <vector>#include <utility>#include <stack>#include <queue>#include <iostream>#include <algorithm>template<class Num>void read(Num &x){ char c; int flag = 1; while((c = getchar()) < '0' || c > '9') if(c == '-') flag *= -1; x = c - '0'; while((c = getchar()) >= '0' && c <= '9') x = (x<<3) + (x<<1) + (c-'0'); x *= flag; return;}template<class Num>void write(Num x){ if(x < 0) putchar('-'), x = -x; static char s[20];int sl = 0; while(x) s[sl++] = x%10 + '0',x /= 10; if(!sl) {putchar('0');return;} while(sl) putchar(s[--sl]);}const int maxn = 50005, Mod = 1e9 + 7;struct Matrix{ long long a[2][2];}emp, tree[maxn<<2];Matrix operator *(const Matrix &A, const Matrix &B){ Matrix ret = emp; for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) for(int k = 0; k < 2; k++) ret.a[i][j] = (ret.a[i][j] + A.a[i][k]*B.a[k][j])%Mod; return ret; }#define L(x) ((x)<<1)#define R(x) ((x)<<1|1)void update(int x){ tree[x] = tree[L(x)]*tree[R(x)];}void build(int ll,int rr,int si){ if(ll == rr) { for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++) tree[si].a[i][j] = 1; return; } int mid = (ll + rr)>>1; build(ll, mid, L(si)); build(mid + 1, rr, R(si)); update(si);}void change(int k,int x,int y,int ll,int rr,int si){ if(ll == rr) { tree[si].a[x][y] ^= 1; return; } int mid = (ll + rr)>>1; if(k <= mid) change(k, x, y, ll, mid, L(si)); else change(k, x, y, mid + 1, rr, R(si)); update(si);}Matrix query(int l,int r,int ll,int rr,int si){ if(ll == l && rr == r) return tree[si]; int mid = (ll + rr)>>1; if(mid < l) return query(l, r, mid + 1, rr, R(si)); if(r <= mid) return query(l, r, ll, mid, L(si)); return query(l, mid, ll, mid, L(si))*query(mid + 1, r, mid + 1, rr, R(si));}#undef L#undef Rlong long calcu(Matrix P){ return (P.a[0][0] + P.a[0][1] + P.a[1][0] + P.a[1][1])%Mod;}int main(){ int n, m;#ifndef ONLINE_JUDGE freopen("hdu5068.in","r",stdin); freopen("hdu5068.out","w",stdout);#endif while(scanf("%d%d",&n,&m) != EOF) { build(1, n - 1, 1); while(m --) { int op, x, y, z; read(op), read(x), read(y); if(op) read(z), change(x, y - 1, z - 1, 1, n - 1, 1); else write(calcu(query(x, y - 1, 1, n - 1, 1))), puts(""); } }#ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout);#endif return 0;}
0 0
- hdu 5068
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- 事务隔离级别
- iOS开发 单例类,拨打电话以及禁用导航条的侧滑功能和隐藏导航底部的线 跳转系统设置页面
- 关于 Keil µVision4 中出现中文乱码的解决办法
- hive优化四
- Android之闪动的、增长的数字(仿余额宝)
- hdu 5068
- Android系统Burpsuit实现抓https数据包
- 2015/8/6/Swing/线程/服务器对多个客户端通讯
- 今天开始做战斗,回合制战斗代码实现第一篇,从头开始,简单的2d回合制游戏
- 自定义view之音量控制
- Contest 5 1002 MZL's xor【math】
- zookeeper简介
- Android之常见错误总结【入门版】
- java DES加密,解密 (一)