• BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】


    题目链接

    BZOJ4785

    题解

    肝了一个下午QAQ没写过二维线段树还是很难受

    首先题目中的树状数组实际维护的是后缀和,这一点凭分析或经验或手模观察可以得出
    (mod 2)意义下,我们实际求出的区间和是([l - 1,r - 1]),和([l,r])唯一不同的就在于(l - 1)(r)
    所以每个询问实际是询问两个位置值相同的概率

    我们把询问看做二元组((a,b)),其中(a le b),我们要维护((a,b))不同的概率【至于为什么是不同而不是相同,等下说】
    初始概率都为(0)
    对于修改操作([l,r])
    (a in [1,l - 1],b in [l,r])时,此时有(frac{1}{len})的概率改变不等关系
    (a in [l,r],b in [r + 1,n])时,此时有(frac{1}{len})的概率改变不等关系
    (a,b in [l,r])时,此时有(frac{2}{len})的概率改变不等关系

    所以我们可以使用二维线段树维护这些区域的概率值
    如果原不等概率为(p_0),现在有(p_1)的概率改变不等关系
    那么新的概率(p' = p_0(1 - p_1) + (1 - p_0)p_1 = p_0 + p_1 - 2p_0p_1)
    我们记其为概率的合并
    经计算可以得出,这样的合并满足交换律结合律单位元(0)
    所以我们可以使用线段树很方便地维护
    同时为了简化操作,我们采用标记永久化
    现在就可以理解我们为什么要维护不等概率了,因为初值为(0),恰好也为合并运算的单位元

    二维线段树标记永久化的姿势:
    内层线段树将标记储存在路径上的节点中
    外层线段树则通过在修改中途访问内层线段树而就此停止,在询问时询问路径上所有的内层线段树即可

    还要注意空间大小,(O(nlog^2n))要开足够大的空间

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    using namespace std;
    const int maxn = 500005,maxm = 40000005,INF = 1000000000,P = 998244353;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int qpow(int a,int b){
    	int re = 1;
    	for (; b; b >>= 1,a = 1ll * a * a % P)
    		if (b & 1) re = 1ll * re * a % P;
    	return re;
    }
    int inv(int x){return qpow(x,P - 2);}
    int merge(int x,int y){
    	return (((x + y) % P - 2ll * x * y % P) + P) % P;
    }
    int n,m,ls[maxm],rs[maxm],val[maxm],rt[maxn << 2],cnt,ans;
    void modify(int& u,int l,int r,int L,int R,int v){
    	if (!u) u = ++cnt;
    	if (l >= L && r <= R){
    		val[u] = merge(val[u],v);
    		return;
    	}
    	int mid = l + r >> 1;
    	if (mid >= L) modify(ls[u],l,mid,L,R,v);
    	if (mid < R) modify(rs[u],mid + 1,r,L,R,v);
    }
    void query(int u,int l,int r,int pos){
    	if (!u) return; ans = merge(ans,val[u]);
    	if (l == r) return;
    	int mid = l + r >> 1;
    	if (mid >= pos) query(ls[u],l,mid,pos);
    	else query(rs[u],mid + 1,r,pos);
    }
    void Modify(int u,int l,int r,int L,int R,int ll,int rr,int v){
    	if (l >= L && r <= R){
    		modify(rt[u],1,n,ll,rr,v);
    		return;
    	}
    	int mid = l + r >> 1;
    	if (mid >= L) Modify(u << 1,l,mid,L,R,ll,rr,v);
    	if (mid < R) Modify(u << 1 | 1,mid + 1,r,L,R,ll,rr,v);
    }
    void Query(int u,int l,int r,int Pos,int pos){
    	if (rt[u]) query(rt[u],1,n,pos);
    	if (l == r) return;
    	int mid = l + r >> 1;
    	if (mid >= Pos) Query(u << 1,l,mid,Pos,pos);
    	else Query(u << 1 | 1,mid + 1,r,Pos,pos);
    }
    int main(){
    	//freopen("in.in","r",stdin);
    	//freopen("out1.txt","w",stdout);
    	n = read(); m = read();
    	int opt,l,r,len,p;
    	while (m--){
    		opt = read(); l = read(); r = read();
    		if (opt & 1){
    			len = r - l + 1; p = inv(len);
    			if (l > 1){
    				Modify(1,1,n,1,l - 1,l,r,p);
    				modify(rt[0],1,n,1,l - 1,1);
    			}
    			if (r < n){
    				Modify(1,1,n,l,r,r + 1,n,p);
    				modify(rt[0],1,n,r + 1,n,1);
    			}
    			Modify(1,1,n,l,r,l,r,2 * p % P);
    			modify(rt[0],1,n,l,r,(1 - p + P) % P);
    		}
    		else {
    			ans = 0;
    			if (l > 1) Query(1,1,n,l - 1,r);
    			else query(rt[0],1,n,r);
    			printf("%d
    ",(1 - ans + P) % P);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    将Color的格式转变成颜色值
    F# 学习笔记 1 基础学习
    GridView 72般绝技
    前台直接读取Web.config中的值的方法
    根据属性名称 获取对象的属性值
    字符集与字符编码简介(转)
    一个WinForm程序配置信息的简单模型和维护工具——设计说明
    扩展DLL调用扩展DLL的LINK2001错误的解决办法之一
    CProfile : 读写私有INI配置文件
    日记:如何在MFC中使用Winsock2
  • 原文地址:https://www.cnblogs.com/Mychael/p/9047984.html
Copyright © 2020-2023  润新知