hdu 6155
来源:互联网 发布:js定时器setinterval 编辑:程序博客网 时间:2024/06/05 11:10
题目链接:点击打开链接
题解思路:假设dp[i][1]为到i位置尾部是1个个数有几个,dp[i][0]也是如此,那么假设第i个位置放1,那么dp[i][1] = dp[i-1][1]+dp[i-1][0]+1,dp[i][0] = dp[i-1][0],如果第i个位置放0那么dp[i][0] = dp[i-1][1]+dp[i-1][0]+1,dp[i][1] = dp[i-1][1].我们不妨用矩阵来解决这个问题,那么放1的状态转移矩阵应该是
1 1 1 放0的是 1 0 0
0 1 0 1 1 1
0 0 1, 0 0 1,这里也要注意线段树矩阵合并要右边乘以左边,因为矩阵不满足交换律。还有可以把3*3*3的矩阵乘法优化成2*2*3,毕竟最后一行都是相同的且前两个肯定都是零。
代码:
#include<algorithm>#include<cstdio>#include<cstring>#include<iostream>#include<queue>#define inf 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;typedef long long ll;const int mx = 1e5+10,mod = 1e9+7;struct data{ ll marx[3][3];}ma[mx<<2][2];const data da[2] = {{1,0,0,1,1,1,0,0,1},{1,1,1,0,1,0,0,0,1}};bool lazy[mx<<2];char str[mx];ll ans1,ans2;int n,m;void push_up(int rt){ int rt1 = rt<<1,rt2 = rt1|1; int t1 = lazy[rt1],t2 = lazy[rt2],n1 = t1^1,n2 = t2^1; for(int i=0;i<2;i++){ for(int j=0;j<3;j++){ ll c=0; for(int k=0;k<2;k++) c = (c+ma[rt2][t2].marx[i][k]*ma[rt1][t1].marx[k][j]%mod)%mod; ma[rt][0].marx[i][j] =c; } ma[rt][0].marx[i][2] = (ma[rt][0].marx[i][2] + ma[rt2][t2].marx[i][2])%mod; } for(int i=0;i<2;i++){ for(int j=0;j<3;j++){ ll c=0; for(int k=0;k<2;k++) c = (c+ma[rt2][n2].marx[i][k]*ma[rt1][n1].marx[k][j])%mod; ma[rt][1].marx[i][j] =c; } ma[rt][1].marx[i][2] = (ma[rt][1].marx[i][2] + ma[rt2][n2].marx[i][2])%mod; }}void build(int l,int r,int rt){ lazy[rt] = 0; ma[rt][0].marx[2][2] = ma[rt][1].marx[2][2] = 1; if(r==l){ int c = str[r]-'0'; ma[rt][0] = da[c],ma[rt][1] = da[c^1]; return ; } int mid = (l+r)>>1; build(lson); build(rson); push_up(rt);}void push_down(int rt){ if(lazy[rt]){ lazy[rt<<1] ^= 1; lazy[rt<<1|1] ^= 1; lazy[rt] = 0; }}void update(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r) { lazy[rt] ^= 1; return ; } push_down(rt); int mid = (l+r)>>1; if(mid>=L) update(L,R,lson); if(mid<R) update(L,R,rson); push_up(rt);}void query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r){ ll nx,ny; bool ts = lazy[rt]; nx = ma[rt][ts].marx[0][0]*ans1%mod; nx = (nx+ma[rt][ts].marx[0][1]*ans2+ma[rt][ts].marx[0][2])%mod; ny = ma[rt][ts].marx[1][0]*ans1%mod; ny = (ny+ma[rt][ts].marx[1][1]*ans2+ma[rt][ts].marx[1][2])%mod; ans1 = nx,ans2 = ny; return ; } int mid = (l+r)>>1; push_down(rt); if(mid>=L) query(L,R,lson); if(mid<R) query(L,R,rson); push_up(rt);}int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); scanf("%s",str+1); build(1,n,1); while(m--){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(x&1) update(y,z,1,n,1); else{ ans1 = ans2 = 0; query(y,z,1,n,1); printf("%lld\n",(ans1+ans2)%mod); } } } return 0;}
阅读全文
0 0
- hdu 6155
- hdu 6155
- [HDU 6155] Subsequence Count
- HDU 6155 Subsequence Count
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- solr 从数据库导入数据,全量索引和增量索引
- Vue+Node+MongoDB从开发到正式部署
- Windows7下VS2008试用版到期的解决办法
- C# 并行编程 之 并发集合 (.Net Framework 4.0)
- Java中Date各种相关用法
- hdu 6155
- Android截屏与WebView长图分享经验总结
- 利用Illustrator绘制均匀渐变图片
- 差分数组
- Hadoop入门之NameNode中元数据的容灾
- (Linux技术)设置文件的权限 用户 用户组
- MPAndroidChart直方图使用(BarChart),渐变,滑动
- 刷怪升级
- 纯js 别踩白块游戏解析与源码