首页 > 其他分享 >Chemistry Experiment Codeforces Round 247 (Div. 2) 线段树动态开点,二分

Chemistry Experiment Codeforces Round 247 (Div. 2) 线段树动态开点,二分

时间:2023-05-02 22:22:06浏览次数:48  
标签:int Codeforces mid seg 247 Experiment pos ans id

第一次写的时候还不会线段树的动态开点,写了一个是线段树但是是\(O(N^2)\)的写法,现在用动态开点武装了自己,会了正解\(O(qlog n^2)\)。首先建立一个权值线段树,但这里的权值很大,通过动态开点去建树来节省空间,对于两种操作:

  1. 操作1,常见的动态开点的单点修改
  2. 操作2,二分答案,然后在线段树上二分,假设二分的答案是\(ans\),找到线段树上所有小于\(\leq ans\)的值\(S\)和数量\(SIZE\),判断\(SIZE \times ans - S \geq v\)是否成立

image

更多细节见代码(直接copy板子,有点丑)

#define int long long

const int N = 1e5 + 10;

struct segtree
{
	int l, r, sz, s;
}seg[N * 30];
int n, m, tot = 1, a[N], rlim = 1e10;

void update(int &id)
{
	seg[id].s = seg[seg[id].l].s + seg[seg[id].r].s;
	seg[id].sz = seg[seg[id].l].sz + seg[seg[id].r].sz;
}

void change(int &id, int l, int r, int pos, int val)
{
	if(!id) 
		id = ++tot;
	if(l == r)
	{
		seg[id].s += l * val;
		seg[id].sz += val;
		return;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid)
		change(seg[id].l, l, mid, pos, val);
	else
		change(seg[id].r, mid + 1, r, pos, val);
	update(id);
}

long double query(int id, int l, int r, long double qr)
{
	if(!id)
		return 0;
	if(r <= qr)
	{
		return qr * seg[id].sz - seg[id].s;
	}
	
	int mid = (l + r) >> 1;
	long double ans = 0;
	if(qr <= mid)
		ans = ans + query(seg[id].l, l, mid, qr);
	else if(qr > mid)
		ans = ans + query(seg[id].l, l, mid, qr) + query(seg[id].r, mid + 1, r, qr);
	return ans;
}

bool check(double x, int v)
{
	int root = 1;
	long double ans = query(root, 0, rlim, x);
	if(ans >= v)	
		return true;
	else
		return false;
}

void solve()
{   
	cin>>n>>m;
	for(int i = 1; i <= n; i++)
	{
		cin>>a[i];
		int root = 1;
		change(root, 0, rlim, a[i], 1);
	}
	while(m--)
	{
		int opt;	cin>>opt;
		if(opt == 1)
		{
			int pos, x, root = 1;	cin>>pos>>x;
			change(root, 0, rlim, a[pos], -1);
			a[pos] = x;
			change(root, 0, rlim, a[pos], 1);
		}
		else
		{
			int v;	cin>>v;
			long double l = 0, r = 1e16;
			while(r - l > 1e-6)
			{
				long double mid = (l + r) / 2.0;
				if(check(mid, v))	r = mid;
				else l = mid;
			}
			cout<<l<<endl;
		}
	}	
}

标签:int,Codeforces,mid,seg,247,Experiment,pos,ans,id
From: https://www.cnblogs.com/magicat/p/17368435.html

相关文章

  • Codeforces 280C Game on Tree
    设\(p_i\)为\(i\)涂色或不涂色,\(1\)为涂,\(0\)为不涂,答案即为\(E[\sum_{i=1}^np_i]\)然后转化一下柿子:\(\sum_{i=1}^nE[p_i]\),这就很好求了,单独求每个点\(E[p_i]\)的值就行了考虑对于\(u\)点,\(p_u=1\),即能被涂需要满足其祖先都比其晚涂色假设现在有一个序列里面......
  • Educational Codeforces Round 147 (Rated for Div. 2) 题解
    ALink。模拟,代码。BLink。模拟,代码。CLink。我们设\(c\)为最后相同的字符。性质:我们一定不会删除字符\(c\)。因此以\(c\)为最后字符的操作次数就是不包含字符\(c\)的极大段的最小操作次数的最大值。对于一个长度为\(l(l\ge1)\)的段,它的最小操作次数为\(\l......
  • Codeforces 894D Ralph And His Tour in Binary Country
    预处理出对于\(u\)节点其子树内节点(包括\(u\))与\(u\)的距离,从小到大排序得到\(ds_u\)同时对\(ds_u\)进行前缀和处理\(dh_{u,i}=\sum\limits_{j=1}^{i}ds_{u,j}\)这样设\(tot\)为\(ds_u\)二分得到的\(ds_{u,i}\leh\)的右端点,也即为\(u\)子树内对答案有......
  • Codeforces Round 868 (Div. 2)
    题目链接C核心思路一定要看清楚题目,题目是要我们最小哦。首先看可不可抽像为数学表达式,答案肯定是可以的。x=p1^d1*p2^d2*..*pn^dn;D=\sum{(d1+1)*(d2+1)*(d3+1)*...(*(dn+1))};这个D表示的x的约数的个数,这个公式还是很好理解的,需要牢记。ans=D-n-1;为什么需要减一呢,因为......
  • Codeforces 1229B Kamil and Making a Stream
    \(\gcd\)一个性质:对于正整数\(x\),重复\(x\leftarrow\gcd(x,i)\)(\(i\ge0\))直到\(x=1\),\(x\)出现的值个数上限为\(\log_2(x)+1\)证明:考虑到\(x\)是逐渐变小,则在\(x\)变小的情况下,对于\(x=\prod_{i=1}^kp_i^{c_i}\)(\(p_i\\operatorname{为质数}\))中的\(c_i\)......
  • Codeforces Round 869 (Div. 1)
    C根据初中数学知识,恒成立问题考虑未知数x每一项的系数,然后得到(d+1)个等式,根据前两个就可以推出\(s=\frac{b_{d-1}-a_{d-1}}{da_d}\)且\(a_d=b_d\)但是一直不会用题目给的n个点值求出最高的两项系数(或它们的比值),并且怀疑是否把(d+1)个等式全部用到会更好做,然后两个方向分别搞了......
  • Codeforces Gym 103439D - LIS Counting(猜结论+状压)
    一道需要一些猜结论技巧的中档题。首先突破口在于排列长度恰好等于不是额外输入的某个数\(k\)而是LDS与LIS的乘积,这显然启示我们去找一些性质。根据dilworth定理,最长反链等于最小链覆盖,故LIS的长度,就是最少需要的递减数列的个数使得每个元素被覆盖至少一次,而每个递减数......
  • Codeforces Round 869 (Div. 2) A-C
    目录A.Politics思路代码B.Indivisible题意思路代码C.AlmostIncreasingSubsequence题意思路代码A.Politics思路与第\(1\)个人的意见不同的人都要删除代码#include<bits/stdc++.h>usingnamespacestd;intmain(){ intT; cin>>T; while(T--) { intn,m; ci......
  • Codeforces Round 869 (Div. 2)
    Preface一把回到紫名还是很舒服的,D题手比较稳猜了点性质水过主要还是C脑抽了想了挺久才看出来是个丁真题,不然最后过了D之后30min可以看看E的由于要写学校的图论专题所以接下来一段时间的CF补题计划就要先停一停了A.Politics傻逼题,当某个人的串和第一个人有任意一个位置不同......
  • Codeforces Round 823 (Div. 2)C
    C.MinimumNotation思路:我们可以进行的操作时将一个位置的数删除然后在任意位置处添加一个比当前数大1并且小于9的数,所以我们的操作只会让一个数变大,我们统计一个最大值的后缀,贪心的考虑如果当前数的后面有比他小的数的话,我们就需要让这个小的数往前走才能使字典序变小,如果当前......