【SDOI2015】【BZOJ4085】音质检测quality
来源:互联网 发布:jupyter notebook编程 编辑:程序博客网 时间:2024/04/28 04:21
4085: [Sdoi2015]quality
Time Limit: 80 Sec Memory Limit: 512 MB
Submit: 79 Solved: 27
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
HINT
Source
题面请去Vijos看.(目前Vijos需要翻墙
线段树+矩乘,在线段树里维护了9个量来做…
矩阵构建分2*2和3*3两种方式,这是在rank榜上产生这么大速度差异的主要原因
我写的是3*3的,但是3*3的矩阵有两个位置是没什么用的,可以拿掉来省下一部分时间
为了跑得快,可以预处理2的幂次的矩阵.
挺好理解的,主要是难写…
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 300010#define GET (ch>='0'&&ch<='9')#define P 1000000007#define lchild rt<<1,l,mid#define rchild rt<<1|1,mid+1,r#define ln rt<<1#define rn rt<<1|1using namespace std;inline void in(int &x){ char ch=getchar();x=0; while (!GET) ch=getchar(); while (GET) x=x*10+ch-'0',ch=getchar();}int a,b,inv,f1,f2;int n,m,v[MAXN*3][4];char ch[10];struct matrix{ int a[3][3]; friend inline matrix operator * (const matrix& A,const matrix& B) { matrix ret; ret.a[0][0]=(1ll*A.a[0][0]*B.a[0][0]+1ll*A.a[0][1]*B.a[1][0])%P; ret.a[0][1]=(1ll*A.a[0][0]*B.a[0][1]+1ll*A.a[0][1]*B.a[1][1])%P; ret.a[0][2]=(1ll*A.a[0][0]*B.a[0][2]+1ll*A.a[0][1]*B.a[1][2]+A.a[0][2])%P; ret.a[1][0]=(1ll*A.a[1][0]*B.a[0][0]+1ll*A.a[1][1]*B.a[1][0])%P; ret.a[1][1]=(1ll*A.a[1][0]*B.a[0][1]+1ll*A.a[1][1]*B.a[1][1])%P; ret.a[1][2]=(1ll*A.a[1][0]*B.a[0][2]+1ll*A.a[1][1]*B.a[1][2]+A.a[1][2])%P; ret.a[2][0]=ret.a[2][1]=0;ret.a[2][2]=1;return ret; }}Pow2[64];inline int Pow(int a,int b){ int ret=1; for (a%=P;b;b>>=1,a=1ll*a*a%P) if (b&1) ret=(1ll*ret*a%P); return ret;}struct Matrix{ int a[9][9]; Matrix() { memset(a,0,sizeof(a)); } friend inline Matrix operator * (const Matrix& A,const Matrix& B) { static Matrix ret;memset(ret.a,0,sizeof(ret.a)); for (int i=0;i<9;i++) for (int j=0;j<9;j++) for (int k=0;k<9;k++) { ret.a[i][j]+=1ll*A.a[i][k]*B.a[k][j]%P; if (ret.a[i][j]>=P) ret.a[i][j]-=P; } return ret; }}mat[4][22],I;inline void calc(int x){ if (x==1) { f1=1;f2=2;return; } static matrix f;f=Pow2[0];x-=2; for (int i=1;x;x>>=1,i++) if (x&1) f=f*Pow2[i]; f1=(2ll*f.a[1][0]+f.a[1][1]+f.a[1][2])%P;f2=(2ll*f.a[0][0]+f.a[0][1]+f.a[0][2])%P;}struct seg{ int l,r,lflag,rflag,val[9]; inline void init(int fa,int fa_i,int fb,int fb_i) { val[0]=1ll*fa*fb%P;val[1]=1ll*fa*fb_i%P;val[2]=1ll*fa_i*fb%P;val[3]=1ll*fa_i*fb_i%P; val[4]=fa;val[5]=fa_i;val[6]=fb;val[7]=fb_i;val[8]=1; }}tree[1048576+10],ans;void init(int opt,int x,int y,int z){ mat[opt][0]=I; if (opt==0) mat[opt][1].a[0][2]=1,mat[opt][1].a[1][3]=1,mat[opt][1].a[2][0]=y,mat[opt][1].a[2][2]=x,mat[opt][1].a[2][6]=z, mat[opt][1].a[3][1]=y,mat[opt][1].a[3][3]=x,mat[opt][1].a[3][7]=z,mat[opt][1].a[4][5]=1,mat[opt][1].a[5][4]=y, mat[opt][1].a[5][5]=x,mat[opt][1].a[5][8]=z,mat[opt][1].a[6][6]=1,mat[opt][1].a[7][7]=1,mat[opt][1].a[8][8]=1; else if (opt==1) mat[opt][1].a[0][1]=1,mat[opt][1].a[1][0]=y,mat[opt][1].a[1][1]=x,mat[opt][1].a[1][4]=z,mat[opt][1].a[2][3]=1, mat[opt][1].a[3][2]=y,mat[opt][1].a[3][3]=x,mat[opt][1].a[3][5]=z,mat[opt][1].a[4][4]=1,mat[opt][1].a[5][5]=1, mat[opt][1].a[6][7]=1,mat[opt][1].a[7][6]=y,mat[opt][1].a[7][7]=x,mat[opt][1].a[7][8]=z,mat[opt][1].a[8][8]=1; else if (opt==2) mat[opt][1].a[0][0]=y,mat[opt][1].a[0][2]=x,mat[opt][1].a[0][6]=z,mat[opt][1].a[1][1]=y,mat[opt][1].a[1][3]=x, mat[opt][1].a[1][7]=z,mat[opt][1].a[2][0]=1,mat[opt][1].a[3][1]=1,mat[opt][1].a[4][4]=y,mat[opt][1].a[4][5]=x, mat[opt][1].a[4][8]=z,mat[opt][1].a[5][4]=1,mat[opt][1].a[6][6]=1,mat[opt][1].a[7][7]=1,mat[opt][1].a[8][8]=1; else mat[opt][1].a[0][0]=y,mat[opt][1].a[0][1]=x,mat[opt][1].a[0][4]=z,mat[opt][1].a[1][0]=1,mat[opt][1].a[2][2]=y, mat[opt][1].a[2][3]=x,mat[opt][1].a[2][5]=z,mat[opt][1].a[3][2]=1,mat[opt][1].a[4][4]=1,mat[opt][1].a[5][5]=1, mat[opt][1].a[6][6]=y,mat[opt][1].a[6][7]=x,mat[opt][1].a[6][8]=z,mat[opt][1].a[7][6]=1,mat[opt][1].a[8][8]=1; for (int i=2;i<=20;i++) mat[opt][i]=mat[opt][i-1]*mat[opt][i-1];}inline void push_up(int rt){ for (int i=0;i<9;i++) tree[rt].val[i]=(tree[ln].val[i]+tree[rn].val[i])%P;}inline void upd(int rt,Matrix Pw[],int b){ for (int i=1;b;b>>=1,i++) if (b&1) { int tmp[9];memset(tmp,0,sizeof(tmp)); for (int j=0;j<9;j++) for (int k=0;k<9;k++) { tmp[j]+=1ll*Pw[i].a[j][k]*tree[rt].val[k]%P; if (tmp[j]>=P) tmp[j]-=P; } for (int j=0;j<9;j++) tree[rt].val[j]=tmp[j]; }}inline void calc(int rt,int a,int b){ if (a!=0) upd(rt,a<0?mat[2]:mat[0],a<0?-a:a); if (b!=0) upd(rt,b<0?mat[3]:mat[1],b<0?-b:b);}inline void push_down(int rt){ calc(rt,tree[rt].lflag,tree[rt].rflag); if (tree[rt].l==tree[rt].r) { tree[rt].lflag=tree[rt].rflag=0;return; } if (tree[rt].lflag!=0||tree[rt].rflag!=0) tree[ln].lflag+=tree[rt].lflag,tree[rn].lflag+=tree[rt].lflag, tree[ln].rflag+=tree[rt].rflag,tree[rn].rflag+=tree[rt].rflag; tree[rt].lflag=tree[rt].rflag=0;}void build(int rt=1,int l=2,int r=n-1){ tree[rt].l=l;tree[rt].r=r; if (l==r) { tree[rt].init(v[l-1][2],v[l-1][3],v[r+1][0],v[r+1][1]);return; } int mid=(l+r)>>1;build(lchild);build(rchild);push_up(rt);}void modify(int rt,int l,int r,int opt){ int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1; if (l<=L&&r>=R) { if (opt==0) tree[rt].lflag++; else if (opt==1) tree[rt].rflag++; else if (opt==2) tree[rt].lflag--; else tree[rt].rflag--; return; } push_down(rt); if (r<=mid) modify(ln,l,r,opt); else if (l>mid) modify(rn,l,r,opt); else modify(ln,l,mid,opt),modify(rn,mid+1,r,opt); push_down(ln);push_down(rn);push_up(rt);}void Modify(int opt,int l,int r){ if (l>r) return; modify(1,l,r,opt);}void query(int rt,int l,int r){ push_down(rt); int L=tree[rt].l,R=tree[rt].r,mid=(L+R)>>1; if (l<=L&&r>=R) { for (int i=0;i<9;i++) { ans.val[i]+=tree[rt].val[i]; if (ans.val[i]>=P) ans.val[i]-=P; } return; } if (r<=mid) query(ln,l,r); else if (l>mid) query(rn,l,r); else query(ln,l,mid),query(rn,mid+1,r);}int main(){ in(n);in(m);in(a);in(b);a%=P;b%=P;int u,l,r;inv=Pow(a,P-2); for (int i=0;i<9;i++) I.a[i][i]=1; Pow2[0].a[0][0]=Pow2[0].a[1][1]=Pow2[0].a[2][2]=1; Pow2[1].a[0][0]=Pow2[1].a[1][0]=Pow2[1].a[2][2]=1; Pow2[1].a[0][1]=a;Pow2[1].a[0][2]=b; for (int i=2;i<=32;i++) Pow2[i]=Pow2[i-1]*Pow2[i-1]; for (int i=1;i<=n;i++) in(u),calc(u), v[i][0]=f1,v[i][1]=f2, v[i][2]=(1ll*v[i][0]*a+b+v[i][1])%P, v[i][3]=(1ll*v[i][1]*a+v[i][2]+b)%P; init(0,1,a,b);init(1,1,a,b); if (a) init(2,inv,(P-inv)%P,1ll*b*(P-inv)%P),init(3,inv,(P-inv)%P,1ll*b*(P-inv)%P); else init(2,0,1,(P-b)%P),init(3,0,1,(P-b)%P); build(); while (m--) { scanf("%s",ch+1);in(l);in(r); if (ch[1]=='p') Modify(0,l+1,min(r+1,n-1)),Modify(1,max(l-1,2),r-1); if (ch[1]=='m') Modify(2,l+1,min(r+1,n-1)),Modify(3,max(l-1,2),r-1); if (ch[1]=='q') { for (int i=0;i<9;i++) ans.val[i]=0; if (l+1<=r-1) query(1,l+1,r-1);printf("%d\n",ans.val[0]); } }}
1 0
- 【SDOI2015】【BZOJ4085】音质检测quality
- [BZOJ4085][Sdoi2015]quality && 线段树 (TLE)
- bzoj 4085: [Sdoi2015]音质检测
- 关于如何判断asterisk的音质 voip voice quality,QoS
- MP3 Quality Modifier(MP3音质优化)V2.1
- 音质检测的算法创新与实现
- 音质检测的算法创新与实现
- 关于asterisk的音质的度量,MOS,Mean Opinion Score (MOS) - A Measure Of Voice Quality
- Quality
- SDOI2015游记
- 如何进行音质评价
- 学习笔记:音频音质
- 关于音质和比特率
- 关于音质评价
- 音色与音质训练
- 好听音质配置
- 蓝牙音频音质探讨
- 功放测试和音质
- Android 图片三级缓存之内存缓存(告别软引用(SoftRefrerence)和弱引用(WeakReference))
- 《JS权威指南》学习笔记(四):对象
- javascript自带的保留有效数字方法
- android apk反编译方法
- JAVA 实现简单的日志工具
- 【SDOI2015】【BZOJ4085】音质检测quality
- HDFS副本放置策略
- hibernate多对一单向关联
- Implement strStr()--leetcode
- 2016年软考程序员模拟预测习题20题
- fork()、vfork()、clone()的区别
- Netty in Action (十八) 第八章节 Bootstrapping
- String StringBuffer StringBuilder
- iOS代码布局