您的位置:首页 > 其它

BZOJ4785: [Zjoi2017]树状数组

2017-04-01 03:43 183 查看

错的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));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: