BZOJ4785: [Zjoi2017]树状数组
错的bit相当于查后缀和,所以就是求$l-1$和$r$相等的概率,转成二维限制,分类讨论一下就好了。
注意特判$l=1$。
注意没有可减性,因为存在零元$\frac12$,若记录零元个数就具备了可减性。
写二维线段树的话注意空间。
#include<cstdio> #define I (J+1) #define J (i+j>>1) #define P (k<<1) #define S (P^1) typedef unsigned long long ll; const int p=998244353; int cal(ll a,ll b){ return(a*(1+(p-b)*2)+b)%p; } const int N=1e5; struct node{ int i,j,a,b; }e[N*300]; int l; void ins(int a,int b,int x,int i,int j,int&k){ if(!k)k=++l; e[k].a=cal(e[k].a,a); e[k].b=cal(e[k].b,b); if(i!=j) x<I?ins(a,b,x,i,J,e[k].i):ins(a,b,x,I,j,e[k].j); } int ask(int node::*p,int x1,int x2,int i,int j,int k){ return!k?0:x1==i&&j==x2?e[k].*p:x2<I?ask(p,x1,x2,i,J,e[k].i):x1>J?ask(p,x1,x2,I,j,e[k].j):cal(ask(p,x1,J,i,J,e[k].i),ask(p,I,x2,I,j,e[k].j)); } int n,r[N*4]; void ins(int a,int b,int x,int y,int i,int j,int k){ ins(a,b,x,1,n,r[k]); if(i!=j) y<I?ins(a,b,x,y,i,J,P):ins(a,b,x,y,I,j,S); } void ins(int z,int x,int y){ ins(z,z*2%p,x,y,1,n,1); } int ask(int node::*p,int x1,int x2,int y1,int y2,int i,int j,int k){ return y1==i&&j==y2?ask(p,x1,x2,1,n,r[k]):y2<I?ask(p,x1,x2,y1,y2,i,J,P):y1>J?ask(p,x1,x2,y1,y2,I,j,S):cal(ask(p,x1,x2,y1,J,i,J,P),ask(p,x1,x2,I,y2,I,j,S)); } int ask(int node::*p,int x1,int x2,int y1,int y2){ return ask(p,x1,x2,y1,y2,1,n,1); } int inv(ll a){ ll s=1; for(int n=p-2;n;n>>=1){ if(n&1)s=s*a%p; a=a*a%p; } return s; } int main(){ int m,o,u,v; scanf("%d%d",&n,&m); int w=1; while(m--){ scanf("%d%d%d",&o,&u,&v); if(o==1){ w^=1; ins(inv(v-u+1),u,v); }else{ if(--u) printf("%d\n",cal(cal(cal(ask(&node::b,1,u,v,n),ask(&node::a,1,u,u,v-1)),ask(&node::a,u+1,v,v,n)),1)); else printf("%d\n",cal(ask(&node::a,1,v,v,n),w)); } } }