首页 > 其他分享 >题解:洛谷 P4879 ycz的妹子

题解:洛谷 P4879 ycz的妹子

时间:2025-01-21 19:03:39浏览次数:3  
标签:洛谷 int 题解 void Tree tr modify ID P4879

题目https://www.luogu.com.cn/problem/P4879感觉还比较简单的线段树。

首先我们先建立一棵线段树(范围:[1,5\times 10^5])。

void build(int k,int l,int r){
	tr[k]={l,r};
	if(l==r){
		Tree[k]=a[l],c[k]=(l<=n);
		return;
	}
	int mid=(l+r)>>1ll;
	build(k<<1ll,l,mid);
	build((k<<1ll)|1ll,mid+1,r);
	push_up(k);
}

对于操作一

线段树单点修改,我们缩小区间范围,直到找到 x 所在的叶子节点,然后将叶子节点减去 y

对于操作二

先找到 x 所在的叶子节点,然后将数字顶替掉。

操作一 + 操作二实现:

void modify(int k,int x,int val,bool flag){
	if(tr[k].l==tr[k].r&&tr[k].l==x){
		c[k]=(!flag?1:c[k]);
		Tree[k]=(flag?Tree[k]+val:val);
		return;
	}
	int mid=(tr[k].l+tr[k].r)>>1ll;
	if(mid>=x){
		modify(k<<1ll,x,val,flag);
	}else{
		modify((k<<1ll)|1ll,x,val,flag);
	}
	push_up(k);
}

对于操作三

最难的一个点了好吧(其实也没那么难)。

我们维护区间中的妹子数量(c 数组的用处就是这个)。

当然,如果你更新的是右区间,找的不是右边区间的第 x 个妹子,而是 x 减去左边区间的妹子数量。

void Delete(int k,int x){
	if(tr[k].l==tr[k].r&&c[k]==x){
		Tree[k]=0,c[k]--;
		return;
	}
	if(c[k<<1ll]>=x){
		Delete(k<<1ll,x);
	}else{
		Delete((k<<1ll)|1ll,x-c[k<<1ll]);
	}
	push_up(k);
}

对于操作四

嗯……直接输出根节点的值就好了(就是这么简单)。

实现

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[500005],Tree[2000005],c[2000005];
struct node{
	int l,r;
}tr[2000005];
void push_up(int k){
	Tree[k]=Tree[k<<1ll]+Tree[(k<<1ll)|1ll];
	c[k]=c[k<<1ll]+c[(k<<1ll)|1ll];
}
void build(int k,int l,int r){
	tr[k]={l,r};
	if(l==r){
		Tree[k]=a[l],c[k]=(l<=n);
		return;
	}
	int mid=(l+r)>>1ll;
	build(k<<1ll,l,mid);
	build((k<<1ll)|1ll,mid+1,r);
	push_up(k);
}
void modify(int k,int x,int val,bool flag){
	if(tr[k].l==tr[k].r&&tr[k].l==x){
		c[k]=(!flag?1:c[k]);
		Tree[k]=(flag?Tree[k]+val:val);
		return;
	}
	int mid=(tr[k].l+tr[k].r)>>1ll;
	if(mid>=x){
		modify(k<<1ll,x,val,flag);
	}else{
		modify((k<<1ll)|1ll,x,val,flag);
	}
	push_up(k);
}
void Delete(int k,int x){
	if(tr[k].l==tr[k].r&&c[k]==x){
		Tree[k]=0,c[k]--;
		return;
	}
	if(c[k<<1ll]>=x){
		Delete(k<<1ll,x);
	}else{
		Delete((k<<1ll)|1ll,x-c[k<<1ll]);
	}
	push_up(k);
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,1,500000);
	int x,y;
	char ID;	
	while(m--){
		cin>>ID;
		if(ID=='C'){
			cin>>x>>y;
			modify(1,x,-y,true);
		}else if(ID=='I'){
			cin>>x>>y;
			modify(1,x,y,false);
		}else if(ID=='D'){
			cin>>x;
			Delete(1,x);
		}else{
			cout<<Tree[1]<<'\n';
		}
	}
	return 0;
}

标签:洛谷,int,题解,void,Tree,tr,modify,ID,P4879
From: https://blog.csdn.net/ATION001/article/details/145268678

相关文章

  • 题解:洛谷 P1351 [NOIP2014 提高组] 联合权值
    题目https://www.luogu.com.cn/problem/P1351我们可以发现,若点对  的距离为 ,则它们一定会经过一个中转点,因此我们考虑枚举中转点 ,然后枚举与  有直接边连接的两个点,按照题意统计答案即可。#include<bits/stdc++.h>usingnamespacestd;#pragmaG++optimisze(3,"Ofas......
  • 洛谷题单指南-线段树的进阶用法-P2839 [国家集训队] middle
    原题链接:https://www.luogu.com.cn/problem/P2839题意解读:求左端点在[a,b]之间,右端点在 [c,d]之间的子区间中,最大的中位数。解题思路:1、直男暴力法枚举左、右端点,然后排序计算中位数,这样的复杂度在n*n*logn,显然不可行。2、渣男巧妙法首先,要重新来看待何为中位数。设一段......
  • 【题解】Luogu P4340 [SHOI2016] 随机序列
    简单手摸后发现,答案就是这么一个式子:\[(3^{n-1}-3^{n-2})a_1+(3^{n-2}-3^{n-3})a_1a_2+\dots+(3^1-3^0)a_1a_2\dotsa_{n-1}+a_1a_2\dotsa_n\]啊当然证明也是好证的,对于\(a_1\)这一项,它后面放+或-都会对系数加一,而放*不会影响系数,因此系数就是总数的三分之二。其它前缀......
  • 题解:P3823 [NOI2017] 蚯蚓排队
    题目链接https://www.luogu.com.cn/problem/P3823分析先解决队伍的合并与分离问题。使用链表结构,分别维护每只蚯蚓的前驱和后继即可。然后考虑如何统计答案。可以对每只蚯蚓的“向后\(k\)数字串”使用字符串哈希的方式获得哈希值,再用一个哈希表存储每个哈希值出现的次数。对......
  • 2024 (ICPC) Jiangxi Provincial Contest I 题 Neuvillette Circling题解
    简单思路一个圆套中了几个点,如果不断缩小这个圆,那么最终的结果有两种有两个点卡住了这个圆,且这两点一定是直径有三个或者三个以上的点卡住了这个圆,圆心在这三个点围成的三角形的外接圆圆心。因此我们枚举两点作为直径,或者枚举三个点作为圆的内接三角形,求这个三角形的外接圆......
  • 2024 (ICPC) Jiangxi Provincial Contest L 题 Campus 题解
    简单思路首先对于所有的出口求一遍最短路,由于出口只会打开并关闭一次,所以大门的开启状态是相当有限的(最多大概30种),我们对于每一种状态直接暴力求答案最后输出即可。复杂度大概\(O(knlogn)\)参考代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;type......
  • 洛谷 P3397:地毯 ← “二维前缀和 + 二维差分”模板题
    【题目来源】https://www.luogu.com.cn/problem/P3397【题目描述】在n×n的格子上有m个地毯。给出这些地毯的信息,问每个点被多少个地毯覆盖。【输入格式】第一行,两个正整数n,m。意义如题所述。接下来m行,每行两个坐标(x1,y1)和(x2,y2),代表一块地毯,左上角......
  • Codeforces Round 998 (Div. 3) 部分题解
    写题解的时候这场在评测,就不放代码了。E.GraphComposition题意给两个无向简单图,对图\(1\)添加若干条边或删除若干条边,使得两图的连通性一致,最少需要变更多少条边。题解求出图\(2\)的连通性,考虑图\(1\)的所有边,若违背了图\(2\)联通性的要删除(图\(2\)不联通但图\(......
  • 20250120 T2 simu题解
    简单模拟(simu)【题目描述】给定$a_1,a_2,\ldots,a_n$和$b_1,b_2,\ldots,b_n$。对于所有整数$x\in[l,r]$,模拟以下过程并求出变量$res$的最终的值。res=0fori=1ton:ifx>=a[i]:x=x-a[i]res=res+b[i]【输入格式】......
  • 「题解」二进制与一
    传送门:水滴、洛谷题目大意:给定一个正整数$n$,给出操作次数$p$。每次操作让$n$加上一个非负整数$x$,使得$n$的第$k$位为$0$(从右往左数)。如果本身为$1$就不用操作。且每次操作$n+x$回影响后续操作。问$x$的和是多少。首先我们要知道,判断$n$的第$k$位是否为$......