首页 > 其他分享 >线段树与二分操作 vases and flowers ——hdu 4614

线段树与二分操作 vases and flowers ——hdu 4614

时间:2024-09-12 10:35:33浏览次数:1  
标签:hdu int sum tree mid vases lazy flowers id

操作1,的关键是找到第一只和最后一只空花瓶,完全可以利用二分法查找,找第一只花瓶可以在[X,N]内查找,第一个位置pos1,最后一只花瓶则在[POS1,N]中找,然后更新[POS1,POS2],全部置1即可
代码:

#include<iostream>
using namespace std;
const int N = 5e4 + 5;
struct node {
	int lazy;
	int sum;  //sum代表空花瓶的数量
}tree[N<<2];

int ls(int i) { return i << 2; }
int rs(int i) { return i << 2 | 1; }

int t, n, m, x, y, k;

//以下四个函数都是线段树的基本操作
void pushdown(int id, int l, int r) {
	if (tree[id].lazy == -1) { return; }

	int mid = (l + r) >> 1;

	tree[ls(id)].sum = (mid - l + 1) * tree[id].lazy;
	tree[rs(id)].sum = (r - mid) * tree[id].lazy;
	tree[ls(id)].lazy = tree[rs(id)].lazy = tree[id].lazy;

	tree[id].lazy = -1;
}

void pushup(int id) {
	tree[id].sum = tree[ls(id)].sum + tree[rs(id)].sum;
}

void build(int id, int l, int r) {
	if (l == r) {
		tree[id].lazy = -1;
		tree[id].sum = 0;
	}
	int mid = (l + r) >> 1;
	build(ls(id), l, mid);
	build(rs(id), mid + 1, r);
	tree[id].lazy = -1;
	pushup(id);
}

int query(int id, int l, int r, int x, int y) {
	if (x <= l && y >= r) return tree[id].sum;
	int ans = 0;
	pushdown(id, l, r);
	int mid = (l + r) >> 1;
	if (x <= mid) ans += query(ls(id), l, mid, x, y);
	if (y > mid) ans += query(rs(id), mid + 1, r, x, y);
	return ans;
}

void update(int id, int l, int r, int x, int y, int d) {  //d=1代表花瓶是空的,d=0代表花瓶是满的
	if (x <= l && y >= r) {
		tree[id].sum = (r - l + 1) * d;
		tree[id].lazy = d;
		return;
	}
	pushdown(id, l, r);
	int mid = (l + r) >> 1;
	if (x <= mid) update(ls(id), l, mid, x, y, d);
	if (y > mid) update(rs(id), mid + 1, r, x, y, d);
	pushup(id);
}

int binarysearch(int x, int n, int f) {
	int l = x, int r = n;
	while (l < r) {
		int mid = (l + r) >> 1;
		int t = query(1, 1, n, x, mid); //查找左边部分,从左边判断第f个空花瓶是在左边还是右边
		if (t >= f) r = mid;
		else l = mid + 1;
	}
	return r;
}

int main() {
	cin >> t;
	while (t--) {
		cin >> n >> m;
		build(1, 1, n);
		for (int i = 1; i <= m; i++) {
			cin >> k >> x >> y;
			if (k == 1) {
				x++;  //保证区间为[1,N]
				//首先查询[X,N]中是否有空花瓶
				int t = query(1, 1, n, x, n);
				if (t == 0) {
					cout << "Can not put any one" << endl;
				}
				else {
					t = min(y, t);  //计算需要插花数量,此时的y代表收到花的数量
					int s = binarysearch(x, n, 1);  //搜索第一个空花瓶
					int t = binarysearch(s, n, t);  //搜索最后一个空花瓶
					cout << s - 1 << " " << t - 1 << endl;
					update(1, 1, n, s, t, 0);
				}
			}
			else {
				x++; y++;
				int t = query(1, 1, n, x, y);
				update(1, 1, n, x, y, 1);
				cout << y - x + 1 - t;
			}
		}
		cout << endl;
	}
	return 0;
}

标签:hdu,int,sum,tree,mid,vases,lazy,flowers,id
From: https://www.cnblogs.com/oQAQo/p/18407051

相关文章

  • 线段树 transformation——hdu 4578
    问题描述:给定一个数列,数列中所有元素都初始化为0,对其执行多种区间操作操作1:add修改:对区间[L,R]内的所有数加c操作2:multi修改:对区间[L,R]内所有数乘以c操作3:change操作:把区间[L,R]内所有数改为c操作4:sum操作:对区间中的每个数的p次方求和。1<=p<=3输入:有不超过10个测试用例。......
  • 线段树can you answer these queries-------hdu4027
    问题描述:给定一个数列,要求对指定区间内所有数开方,输出查询区间和输入:有很多个测试用例,每个用例第一行输出一个整数N,表示数列有N个数,1<=N<=100000;第二行输入N个整数E,E<2e63;第三行输入整数M,表示M种操作,1<=M<=100000;之后的M行,每行输入3个整数TXY。T=0,表示修改,将区间[L,R]内所......
  • HDU5512
    本题考察裴蜀定理,刚刚学过就写了一下。能够维修的塔就是\(a,b,a-b,a+b,a+2b,a-2b,2a-b,2a+b...\),上述这些塔的位置就符合ax-by的格式,也就是可以使用裴蜀定理了。裴蜀定理为\(ax+by=gcd(a,b)\),也就是说上述的所有能够维修的塔的位置都是\(gcd(a,b)\)的整数倍即为\(n/gcd(a,b)\)。那......
  • HDU 1729 Stone Game
    https://ac.nowcoder.com/acm/contest/34655/C有\(n\)个箱子,第\(i\)个箱子最多放\(s_i\)个石子,当前箱子里的石子数为\(c_i\)。两个人轮流往箱子里放石子,而且每一次放的数量都有限制:不能超过当前箱子内石子数的平方。例如箱子里有\(3\)颗石子,那么下一个人就可以放\(1-9\)......
  • 【hdu 7548】SunBian
    题目链接:hdu7548SunBian(2024“钉耙编程”中国大学生算法设计超级联赛(10))思路:一道比较签到的题。先说结论:1.当n=k时A必胜2.当k=1时,n为奇数A胜,否则B胜3.其余情况全都为B胜证明:1.显然n=k时A可以一回合全部取完2.k=1时双方只能轮流来,显然奇数A胜偶数B胜3.此时A是......
  • hdu7438
    题面给定长度为\(N\)的序列\(a\)。一个序列有很多个子序列,每个子序列在序列中出现了若干次。小马想请你输出序列\(a\)每个非空子序列出现次数的立方值的和,答案对\(998244353\)取模。数据范围:\(n,a_i\le250\)。题解一个很高级的trick,"出现次数的立方值"等价于"我......
  • hdu7439
    题面小马给出长度为\(n\)的正整数序列\(f,g\),现以如下方式生成\(n\)个点的有向图:forifrom1ton: forjfromi+1ton: iff[i]<f[j]andg[i]<g[j]: addedgefromitojelse: addedgefromjtoi试求出图中三元环的个数。数据范围:\(......
  • hdu2604
    用f(n)表示n个人满足条件的结果,那么如果最后一个人是m的话,那么前n-1个满足条件即可,就是f(n-1); 如果最后一个是f那么这个还无法推出结果,那么往前再考虑一位:那么后三位可能是:mmf,fmf,mff,fff,其中fff和fmf不满足题意所以我们不考虑,但是如果是 mmf的话那么前n-3可以找满足条件的......
  • HDU-ACM 2024 Day4
    T1001超维攻坚(HDU7469)三维凸包,不会。T1002黑白边游戏(HDU7470)显然这道题没有一个固定的最优策略,所以只能\(\text{dp}\)决策。可以倒着做,设\(f_{i,S}\)表示从后往前进行了第\(i\simm\)轮,第\(i\)轮结束后(在原始意义下是开始前)黑边集合为\(S\),双方使用最优策......
  • HDU 3590 PP and QQ
    题目链接:HDU3590【PPandQQ】思路    树上删边问题,套个反尼姆博弈。    反尼姆博弈是取走最后一个石子的人输掉游戏,所以需要特判一些特殊情况。    1.有堆的石子个数都是1,所以堆数为奇数时,先手必败,否则先手必胜    2.所有堆中存在石子数为......