• [ZJOI2017]树状数组


    以后写题前还是要冷静分析清楚再动手啊.....

    $ Think twice,code once$


    传送门:here

    大致题意:

    有一个写挂的树状数组,$ query$的是后缀和,$ query(0)$时返回$ 0$

    有$ m$次操作,

    $ 1 L R$表示在$ L...R$中等概率选取一个点$ update$

    $ 2 L R$表示求$ query(L,R)$和正确的树状数组$ query$在模$ 2$意义下相同的概率


    先特判掉询问时$ L==1$的情况

    发现相当于询问$ [L-1..n]-[R..n]-[1..R]+[1..L-1]=val[L-1]-val[R]$模$ 2$意义下的值

    这题询问的两个端点$ L,R$不能独立考虑,因为一次$ update$只能选取一个点进行更新

    考虑暴力

    我们枚举一次$ query$前的所有$ update(L,R)$

    如果$ query$的$ L-1$和$ R$均在$ update$区间内,则有$ frac{2}{len}$的概率改变模$ 2$意义下的结果

    否则若只有一个端点在$ update$区间内,则有$ frac{1}{len}$的概率改变模$ 2$意义下的结果

    我们用$ p1,p2$分别表示这次更新和更新前结果为$ 0$的概率,则有$ merge(p1,p2)=p1p2+(1-p1)(1-p2)$

    可以令$ p1=1$然后每次求出$ p2$并进行合并


    考虑用树套树维护这个东西

    对于每一次查询$ L,R$相当于查询坐标$ (L-1,R)$上的结果

    对于每一个$ change(1,L,R)$,我们给矩形内打上$ frac{2}{len}$概率修改的标记,矩形外只包含$ L-1$或只包含$ R$的四块矩形打上$ frac{2}{len}$概率修改的标记

    由于查询的$(L-1,R)$保证$ L-1<R$,因此只包含$ L-1$或只包含$ R$的四块矩形里我们只需要修改两块以节省空间

    由于单点查询可以轻松用标记永久化维护

    洛谷上第$ 13$个点只有修改没有询问,可能需要卡一波空间

    记得特判$ L=1$


     $ my code:$

    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define p 998244353
    #define rt register int
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x = 0; char zf = 1; char ch = getchar();
        while (ch != '-' && !isdigit(ch)) ch = getchar();
        if (ch == '-') zf = -1, ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x * zf;
    }
    void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
    void writeln(const ll y){write(y);putchar('
    ');}
    int i,j,k,m,n,x,y,z,cnt,Cnt;
    ll inv[100010];
    struct segment{
        int ls,rs,val;
    }a[36000010];
    int to[400010];
    int Root,ans;
    inline void merge(int &x,int y){
        x=(1ll*x*y+(1ll-x)*(1-y))%p;
    }
    void Insert(int &x,int L,int R,int L1,int R1,int gl){
        if(L>R1||R<L1)return;
        if(!x)x=++cnt,a[x].val=1;
        if(L>=L1&&R<=R1)return merge(a[x].val,gl);
        const int mid=L+R>>1;
        Insert(a[x].ls,L,mid,L1,R1,gl);
        Insert(a[x].rs,mid+1,R,L1,R1,gl);
    }
    void insert(int &x,int L,int R,int L1,int R1,int L2,int R2,int gl){
        if(L>R1||R<L1)return;if(!x)x=++Cnt;
        if(L>=L1&&R<=R1)return Insert(to[x],1,n,L2,R2,gl);
        const int mid=L+R>>1;
        insert(a[x].ls,L,mid,L1,R1,L2,R2,gl);
        insert(a[x].rs,mid+1,R,L1,R1,L2,R2,gl);
    }
    void Query(int x,int L,int R,int w){
        if(!x)return;merge(ans,a[x].val);
        const int mid=L+R>>1;
        if(w<=mid)Query(a[x].ls,L,mid,w);
        else Query(a[x].rs,mid+1,R,w);
    }
    void query(int x,int L,int R,int w1,int w2){
        if(!x)return;
        Query(to[x],1,n,w2);
        const int mid=L+R>>1;
        if(w1<=mid)query(a[x].ls,L,mid,w1,w2);
        else query(a[x].rs,mid+1,R,w1,w2);
    }
    int main(){
        n=read();m=read();int t=0;
        inv[1]=1;
        for(rt i=2;i<=n;i++)inv[i]=inv[p%i]*(p-p/i)%p;    
        cnt=400000;
        for(rt i=1;i<=m;i++){
            x=read();int L=read(),R=read();
            if(x==1){
                int len=R-L+1,v=1;t++;
                insert(Root,0,n,L,R,L,R,1-2*inv[len]);    
                insert(Root,0,n,L,R,R+1,n,1-inv[len]);        
                insert(Root,0,n,0,L-1,L,R,1-inv[len]);        
            }
            else{
                z=i;ans=1;query(Root,0,n,L-1,R);
                if(L==1&&(t&1))ans=(1-ans)%p;
                (ans+=p)%=p;
                writeln(ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    2009年放假时间安排
    省钱方便网上手机充话费
    为啥不能嵌入html?
    超出套餐流量的GPRS流量费竟然要贵100倍!怎么没有人管呢!这个价格怎么定的呢!
    2008汶川加油!2008中国加油!!
    thinkpad X200 破音特别厉害!郁闷啊!千万不要买水货!
    送走2008,迎接新的2009!
    "上海启明星电子商务有限公司"偷偷扣你的电话钱
    从公司到凯虹
    供应二级新疆细绒棉150吨
  • 原文地址:https://www.cnblogs.com/DreamlessDreams/p/9868527.html
Copyright © 2020-2023  润新知