求助,全WA
查看原帖
求助,全WA
652982
char_phi楼主2023/2/22 17:51

上个帖子忘加代码了,wssb

几个月没学 oi\text{oi} 打个同学组的复健赛

然而这个题一晚上 + 2h\text{+ 2h} 还调不对

思路是直接莽离散化线段树,把涉及到的所有等级都给离散化

每个线段树的叶子节点维护从 [它的真实等级,下一个离散化的真实等级] 这段区间

然而全 WA\text{WA} 了。。

Wrong Answer.wrong answer The answer is wrong: expected = 7082236.410900, found = 7099498.927800

求浇浇/kk

(LZ在线时间不很连续可能不能及时回复)

#include <iostream>
#include <algorithm>
#define char_phi int
#define re register int
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout)
#define Diluc 0
#define Endl cout << '\n'
#define _ ' '
#define Dl cerr << '\n'
#define DMARK cerr << "###"
#define N 100005
using namespace std;

inline void Fastio_setup() { ios :: sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL); }
template<typename T> inline T MAX(T A, T B) { return ((A > B) ? (A) : (B)); }
template<typename T> inline T MIN(T A, T B) { return ((A < B) ? (A) : (B)); }
template<typename T> inline T ABS(T A) { return ((A < 0) ? (-A) : (A)); }

/*
	这什么,O(nlogn)?
	这不对吧
	为啥我一眼切
	难道是一个前缀和+处理一下期望相同的就ok了?
	如果是更改,把更改点以上的同期望改为当前点的同期望
	如果是询问,直接再来一个树状数组统计答案就行了,再乘上概率 1 / (r - l + 1)
	真切了?
	假的
	等级的范围
	zixiangming句
	把所有会出现的等级存起来一起离散化
	然而
	噢
	好像,似乎
	用线段树比较好搞
	直接对所有等级建线段树
	包括询问和修改的等级
	都给他搞上
	然后如果不是相邻的等级
	中间的把贡献算一下扔到靠左的那一个里面
	然后直接求和
	更新的话
	直接把包括这个点到n都给打上lazy
	注意记录嗯,每个线段树节点都记录最右边和最左边的真实等级
	然后打lazy的时候直接打lazy,查询直接查sum + (ter - tel + 1) * lazy
	记录等级直接用set,好查,避免节点重复直接set
	直接sort + unique不比这快
	
	试一嘴样例
	勾八
	
	不搞了
	造个样例搞搞
*/

/*
4 4
1 2
4 3
5 4
7 5
1 1 4
1 4 8
2 6 2
1 4 8

ans
2.7500
10.2000
11.4000

2 1
4 3
2 2
1 1 4

ans
2.2500

2 2
1 3
5 2
1 3 3
1 3 5

ans
3.0000
3.6667
*/

int n, Q;
long long maxlev;
long long Lev[N<<2];

struct Book { long long lev, val; friend bool operator < (Book A, Book B) { return A.lev < B.lev; } };
struct Book bk[N];

struct Question { long long opt, x, y; };
struct Question qus[N];

struct BitTree {
	long long C[N<<2];
	
	#define lowbit(x) ((x) & (-(x)))
	
	inline void Update(int k, long long w) { while (k <= Lev[0]) C[k] += w, k += lowbit(k); }
	inline long long Query(int k) { long long res = 0; while (k > 0) res += C[k], k -= lowbit(k); return res; }
};
struct BitTree Bit;

struct Segment_Tree {
	struct node { long long sum, lz, l, r; };
	struct node tr[N<<4];
	
	#define lson (rt << 1)
	#define rson (rt << 1 | 1)
	#define mid ((l + r) >> 1)
	
	inline void Pushup(int rt) { tr[rt].sum = tr[lson].sum + tr[rson].sum; }
	inline void Pushdown(int rt) {
		tr[lson].lz += tr[rt].lz, tr[rson].lz += tr[rt].lz;
		tr[lson].sum += tr[rt].lz * (tr[lson].r - tr[lson].l + 1);
		tr[rson].sum += tr[rt].lz * (tr[rson].r - tr[rson].l + 1);
		tr[rt].lz = 0;
	}
	
	void Build(int rt, int l, int r) {
		if (l == r) {
			// tr[rt].sum = Bit.Query(Lev[l]) * (Lev[l+1] - Lev[l]);
			tr[rt].l = Lev[l]; tr[rt].r = ((l == Lev[0]) ? (maxlev) : (Lev[l+1]-1));
			tr[rt].sum = Bit.Query(l) * (tr[rt].r - tr[rt].l + 1);
			// cerr << l << _ << tr[rt].l << _ << tr[rt].r << _ << tr[rt].sum << '\n';
			return ;
		}
		Build(lson, l, mid); Build(rson, mid+1, r);
		Pushup(rt);
		tr[rt].l = tr[lson].l, tr[rt].r = tr[rson].r;
	}
	void Update(int rt, int l, int r, int L, int R, long long val) {
		if (L <= l and r <= R)
			{ tr[rt].lz += val; tr[rt].sum += (tr[rt].r - tr[rt].l + 1) * val; return ; }
		if (tr[rt].lz != 0)
			Pushdown(rt);
		if (L <= mid)
			Update(lson, l, mid, L, R, val);
		if (R > mid)
			Update(rson, mid+1, r, L, R, val);
		Pushup(rt);
	}
	long double Query(int rt, int l, int r, int L, int R, char sus) {
		if (L <= l and r <= R)
			return ((sus == true) ? ((long double)tr[rt].sum / (tr[rt].r - tr[rt].l + 1)) : (tr[rt].sum));
		if (tr[rt].lz != 0)
			Pushdown(rt);
		if (R <= mid)
			return Query(lson, l, mid, L, R, sus);
		else if (L > mid)
			return Query(rson, mid+1, r, L, R, sus);
		else 
			return Query(lson, l, mid, L, R, sus) + Query(rson, mid+1, r, L, R, sus);
	}
};
struct Segment_Tree Segtree;

inline void work() {
	cin >> n >> Q;
	long long lev, val;
	for (re i = 1 ; i <= n ; ++ i)
		{ cin >> lev >> val; bk[i] = (Book) { lev, val }; Lev[++ Lev[0]] = bk[i].lev; maxlev = MAX(maxlev, bk[i].lev); }
	// cerr << maxlev << '\n';
	
	long long opt, x, y;
	for (re i = 1 ; i <= Q ; ++ i) {
		cin >> opt >> x >> y; qus[i] = (Question) { opt, x, y }; maxlev = MAX(maxlev, x);
		if (opt == 1) Lev[++ Lev[0]] = x, Lev[++ Lev[0]] = y, maxlev = MAX(maxlev, y);// 注意,线段树操作的时候,是Lev[0],不是n
		else Lev[++ Lev[0]] = x;
	}
	
	
	sort(bk+1, bk+n+1);
	sort(Lev+1, Lev+Lev[0]+1); Lev[0] = unique(Lev+1, Lev+Lev[0]+1) - Lev - 1;//  Lev[Lev[0]+1] = maxlev + 1;
	
	/*bk[n+1].lev = 1145141145141919810;
	for (re i = 1, j = 1 ; i <= n ; ++ i)
		while (Lev[j] < bk[i+1].lev and j <= Lev[0])
			Val[j] = bk[i].val, j ++;
	
	for (re i = 1 ; i <= Lev[0] ; ++ i)
		Bit.Update(i, Val[i]);*/
	
	for (re i = 1 ; i <= n ; ++ i)
		Bit.Update(lower_bound(Lev+1, Lev+Lev[0]+1, bk[i].lev) - Lev, bk[i].val);
	
	/*cerr << Lev[0] << '\n';
	for (re i = 1 ; i <= Lev[0] ; ++ i)
		cerr << Lev[i] << _ << Val[i] << '\n';*/
	
	Segtree.Build(1, 1, Lev[0]);// 细
	
	cout.setf(ios :: fixed); cout.precision(4);
	for (re i = 1 ; i <= Q ; ++ i) {
		if (qus[i].opt == 1) {// 比较可爱的询问
			if (qus[i].x == qus[i].y)
				cout << Segtree.Query(1, 1, Lev[0], lower_bound(Lev+1, Lev+Lev[0]+1, qus[i].x) - Lev, lower_bound(Lev+1, Lev+Lev[0]+1, qus[i].y) - Lev, true) << '\n';
			else 
				cout << Segtree.Query(1, 1, Lev[0], lower_bound(Lev+1, Lev+Lev[0]+1, qus[i].x) - Lev, lower_bound(Lev+1, Lev+Lev[0]+1, qus[i].y) - Lev, false) / (long double)(qus[i].y - qus[i].x + 1) << '\n';
		}
		else 
			Segtree.Update(1, 1, Lev[0], lower_bound(Lev+1, Lev+Lev[0]+1, qus[i].x) - Lev, Lev[0], qus[i].y);
	}
}

#undef int
// #define Genshin_Impact
char_phi main() {
	#ifdef Genshin_Impact
		FBI_OPENTHEDOOR(a, a);
	#endif
	Fastio_setup();
	work();
	return Diluc;
}
2023/2/22 17:51
加载中...