ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[做题记录-数据结构] P3688 [ZJOI2017] 树状数组

2021-09-25 12:03:25  阅读:162  来源: 互联网

标签:__ return 树状 int void mid P3688 ZJOI2017 inline


题意

Problem Link
\(n \leq 5 \times 10^5\)

题解

第一条注意的就是这个是条件概率!
所以每个位置分开算概率是不对的, 所以这不是sb题。
所以得维护\((x, y)\)表示\(a_x = a_y\)的概率。
然后分类讨论一下就好了。
所以还是sb题

/*
	QiuQiu /qq
  ____    _           _                 __                
  / __ \  (_)         | |               / /                
 | |  | |  _   _   _  | |  _   _       / /    __ _    __ _ 
 | |  | | | | | | | | | | | | | |     / /    / _` |  / _` |
 | |__| | | | | |_| | | | | |_| |    / /    | (_| | | (_| |
  \___\_\ |_|  \__,_| |_|  \__, |   /_/      \__, |  \__, |
                            __/ |               | |     | |
                           |___/                |_|     |_|
*/

#include <bits/stdc++.h>

using namespace std;

class Input {
	#define MX 1000000
	private :
		char buf[MX], *p1 = buf, *p2 = buf;
		inline char gc() {
			if(p1 == p2) p2 = (p1 = buf) + fread(buf, 1, MX, stdin);
			return p1 == p2 ? EOF : *(p1 ++);
		}
	public :
		Input() {
			#ifdef Open_File
				freopen("a.in", "r", stdin);
				freopen("a.out", "w", stdout);
			#endif
		}
		template <typename T>
		inline Input& operator >>(T &x) {
			x = 0; int f = 1; char a = gc();
			for(; ! isdigit(a); a = gc()) if(a == '-') f = -1;
			for(; isdigit(a); a = gc()) 
				x = x * 10 + a - '0';
			x *= f;
			return *this;
		}
		inline Input& operator >>(char &ch) {
			while(1) {
				ch = gc();
				if(ch != '\n' && ch != ' ') return *this;
			}
		}
		inline Input& operator >>(char *s) {
			int p = 0;
			while(1) {
				s[p] = gc();
				if(s[p] == '\n' || s[p] == ' ' || s[p] == EOF) break;
				p ++; 
			}
			s[p] = '\0';
			return *this;
		}
	#undef MX
} Fin;

class Output {
	#define MX 1000000
	private :
		char ouf[MX], *p1 = ouf, *p2 = ouf;
		char Of[105], *o1 = Of, *o2 = Of;
		void flush() { fwrite(ouf, 1, p2 - p1, stdout); p2 = p1; }
		inline void pc(char ch) {
			* (p2 ++) = ch;
			if(p2 == p1 + MX) flush();
		}
	public :
		template <typename T> 
		inline Output& operator << (T n) {
			if(n < 0) pc('-'), n = -n;
			if(n == 0) pc('0');
			while(n) *(o1 ++) = (n % 10) ^ 48, n /= 10;
			while(o1 != o2) pc(* (--o1));
			return *this; 
		}
		inline Output & operator << (char ch) {
			pc(ch); return *this; 
		}
		inline Output & operator <<(const char *ch) {
			const char *p = ch;
			while( *p != '\0' ) pc(* p ++);
			return * this;
		}
		~Output() { flush(); } 
	#undef MX
} Fout;

#define cin Fin
#define cout Fout
#define endl '\n'

using LL = long long;
using pii = pair<int, int>;

const int P = 998244353;

int power(int x, int k) {
	int res = 1;
	while(k) {
		if(k & 1) res = 1ll * res * x % P; 
		x = 1ll * x * x % P; k >>= 1;
	}
	return res;
}

inline int Mod(int x) { return x + ((x >> 31) & P); }
inline void pls(int &x, int v) { x = Mod(x + v - P); }
inline void dec(int &x, int v) { x = Mod(x - v); }

const int N = 1e5 + 10;

int n, m;

struct Node {
	Node *ls, *rs;
	int l, r, p;
	Node() {}
	Node(int _l, int _r) : l(_l), r(_r), p(0), ls(NULL), rs(NULL) {}
	inline void down(int q) {
		p = (1ll * p * (P + 1 - q) + 1ll * q * (P + 1 - p)) % P;
	}
} ;

struct SegmentTree1 {
	Node *root;
	SegmentTree1() { root = NULL; }
	void modify(Node *&x, int l, int r, int L, int R, int p) {
		if(x == NULL) x = new Node(l, r);
		if(L <= l && r <= R) { x -> down(p); return ; }
		int mid = (l + r) >> 1;
		if(L <= mid) modify(x -> ls, l, mid, L, R, p);
		if(R > mid) modify(x -> rs, mid + 1, r, L, R, p);
		return ;
	}
	void query(Node *x, int l, int r, int pos, int &p) {
		if(x == NULL) return ;
	//	cerr << x -> p << endl;
		p = (1ll * p * (P + 1 - x -> p) + 1ll * x -> p * (P + 1 - p) ) % P;
		int mid = (l + r) >> 1;
		if(pos <= mid) query(x -> ls, l, mid, pos, p);
		else query(x -> rs, mid + 1, r, pos, p);
	}
	void Modify(int l, int r, int L, int R, int p) {
		modify(root, l, r, L, R, p);
	}
	void Query(int l, int r, int pos, int &p) {
		query(root, l, r, pos, p);
	}
} ;

struct SegmentTree2 {
	#define ls(x) (x << 1)
	#define rs(x) (x << 1 | 1)
	SegmentTree1 tr[N << 2];
	void modify(int x, int l, int r, int L1, int R1, int L2, int R2, int p) {
		if(L1 <= l && r <= R1) {
			//cerr << l << ' ' << r << endl;
			//cerr << x << endl;
			tr[x].Modify(1, n, L2, R2, p); return ;
		}
		int mid = (l + r) >> 1;
		if(L1 <= mid) modify(ls(x), l, mid, L1, R1, L2, R2, p);
		if(R1 > mid) modify(rs(x), mid + 1, r, L1, R1, L2, R2, p);
	}
	void query(int x, int l, int r, int px, int py, int &p) {
		tr[x].Query(1, n, py, p);
		if(l == r) return ;
		int mid = (l + r) >> 1;
		if(px <= mid) query(ls(x), l, mid, px, py, p);
		else query(rs(x), mid + 1, r, px, py, p);
	}
} ;

SegmentTree1 Tree1;
SegmentTree2 Tree2;

int main() {
	cin >> n >> m;
	while(m --) {
		int opt, l, r; cin >> opt >> l >> r;
		if(opt == 1) {
			int p = power(r - l + 1, P - 2);
			if(l > 1) Tree2.modify(1, 1, n, 1, l - 1, l, r, p);
			if(r < n) Tree2.modify(1, 1, n, l, r, r + 1, n, p);
			Tree1.Modify(1, n, l, r, P + 1 - p);
			pls(p, p);
			Tree2.modify(1, 1, n, l, r, l, r, p);
			if(l > 1) Tree1.Modify(1, n, 1, l - 1, 1);
			if(r < n) Tree1.Modify(1, n, r + 1, n, 1);
		}
		else {
			int ans = 0;
			if(l == 1) 
				Tree1.Query(1, n, r, ans);
			else 
				Tree2.query(1, 1, n, l - 1, r, ans);
			cout << (P + 1 - ans) % P << endl;
		}
	}
	return 0;
}

标签:__,return,树状,int,void,mid,P3688,ZJOI2017,inline
来源: https://www.cnblogs.com/clover4/p/15333933.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有