首页 > 其他分享 >洛谷 P2572 [SCOI2010] 序列操作 做题记录

洛谷 P2572 [SCOI2010] 序列操作 做题记录

时间:2024-10-23 08:49:32浏览次数:7  
标签:洛谷 idx int mid read query SCOI2010 P2572 define

其实和小白逛公园差不多,编写代码的难度远大于思路难度,难点是调试:

  • 注意在区间异或 \(1\) 的时候分清代码里的 最长连续 \(1\) 的长度 和 \(1\) 的个数 。
  • 注意查询最长 \(1\) 的时候要用结构体上传,如果用到了定值 len 的话要赋值。
  • 注意如果只用一个 tag 的话,遇到区间异或要对原先 tag 的情况分类讨论。
点击查看代码
#include<bits/stdc++.h>

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define inn(i,n,a) For(i,1,n) a[i]=read();

#define ll long long
#define i128 __int128

using namespace std;
inline int read() {
	int xx= 0;int f= 1;
	char c = getchar();
	while(c<'0'||c>'9') { 
		if(c=='-') f= -1;
		c= getchar();
	}
	while(c>='0'&&c<='9') {
		xx= (xx<<1)+(xx<<3)+(c^48);
		c= getchar();
	}
	return xx*f;
}
#define maxn 100050
struct node {
	int l0,r0,mx0;
	int l1,r1,mx1,cnt1;
	int tag;
	int len;
}tr[maxn<<2];
int n,m;
int a[maxn];
void cg1(node &x,int a1,int a2,int a3) {
	x.l0=a1,x.r0=a2,x.mx0=a3;
}
void cg2(node &x,int a1,int a2,int a3,int a4) {
	x.l1=a1,x.r1=a2,x.mx1=a3,x.cnt1=a4;
}
void cg3(node &x,int a1) {
	x.tag=a1;
}
void modi(node &x,node y,node z) {
	if(y.l0==y.len) x.l0=y.len+z.l0;
	else x.l0=y.l0;
	if(z.r0==z.len) x.r0=z.len+y.r0;
	else x.r0=z.r0;
	x.mx0=max(max(y.mx0,z.mx0),y.r0+z.l0);
	
	if(y.l1==y.len) x.l1=y.len+z.l1;
	else x.l1=y.l1;
	if(z.r1==z.len) x.r1=z.len+y.r1;
	else x.r1=z.r1;
	x.mx1=max(max(y.mx1,z.mx1),y.r1+z.l1);
	x.cnt1=y.cnt1+z.cnt1;
}
void push_up(int idx) { modi(tr[idx],tr[lc(idx)],tr[rc(idx)]); }
void push_down(int idx) {
	node &x=tr[idx],&l=tr[lc(idx)],&r=tr[rc(idx)];
	if(x.tag==0) return ;
	
	if(x.tag==1) {
		int sz=l.len;
		cg1(l,sz,sz,sz);
		cg2(l,0,0,0,0);
		cg3(l,1);
		sz=r.len;
		cg1(r,sz,sz,sz);
		cg2(r,0,0,0,0);
		cg3(r,1);
	} else if (x.tag==2) {
		int sz=l.len;
		cg1(l,0,0,0);
		cg2(l,sz,sz,sz,sz);
		cg3(l,2);
		sz=r.len;
		cg1(r,0,0,0);
		cg2(r,sz,sz,sz,sz);
		cg3(r,2);
	} else {
		node L=l,R=r;
		cg1(l,L.l1,L.r1,L.mx1);
		cg2(l,L.l0,L.r0,L.mx0,L.len-L.cnt1);
		if(l.tag==1) l.tag=2;
		else if(l.tag==2) l.tag=1;
		else if(l.tag==3) l.tag=0;
		else l.tag=3;
		cg1(r,R.l1,R.r1,R.mx1);
		cg2(r,R.l0,R.r0,R.mx0,R.len-R.cnt1);
		if(r.tag==1) r.tag=2;
		else if(r.tag==2) r.tag=1;
		else if(r.tag==3) r.tag=0;
		else r.tag=3;
	}
	x.tag=0;
}
void build(int idx,int l,int r) {
	if(l==r) {
		tr[idx].len=1;
		if(a[l]==1) cg2(tr[idx],1,1,1,1);
		else cg1(tr[idx],1,1,1);
		return ;
	}
	int mid=(l+r)>>1;
	build(lc(idx),l,mid);
	build(rc(idx),mid+1,r);
	tr[idx].len=r-l+1;
	push_up(idx);
//	cout<<idx<<' '<<tr[idx].cnt1<<'\n';
}
int query_cnt(int idx,int l,int r,int L,int R) {
//	cout<<l<<' '<<r<<' '<<L<<' '<<R<<' '<<tr[idx].cnt1<<'\n';
	if(L<=l&&r<=R) return tr[idx].cnt1;
	push_down(idx);
	int mid=(l+r)>>1,res=0;
	if(L<=mid) res+=query_cnt(lc(idx),l,mid,L,R);
	if(R>mid)  res+=query_cnt(rc(idx),mid+1,r,L,R);
	return res;
}
node query(int idx,int l,int r,int L,int R) {
//	cout<<l<<' '<<r<<' '<<L<<' '<<R<<' '<<tr[idx].mx1<<'\n';
	if(L<=l&&r<=R) return tr[idx];
	push_down(idx);
	int mid=(l+r)>>1;
	if(L<=mid&&R<=mid) return query(lc(idx),l,mid,L,R);
	if(R>mid&&L>mid) return query(rc(idx),mid+1,r,L,R);
	node x;
	cg1(x,0,0,0); cg2(x,0,0,0,0); cg3(x,0);
	x.len=r-l+1;
	modi(x,query(lc(idx),l,mid,L,R),query(rc(idx),mid+1,r,L,R));
	return x;
}
void update(int idx,int l,int r,int L,int R,int tag) {
//	cout<<l<<' '<<r<<' '<<L<<' '<<R<<'\n';
	if(L<=l&&r<=R) {
		if(tag==1) {
			int sz=tr[idx].len;
			cg1(tr[idx],sz,sz,sz);
			cg2(tr[idx],0,0,0,0);
			cg3(tr[idx],1);
		} else if(tag==2) {
			int sz=tr[idx].len;
			cg1(tr[idx],0,0,0);
			cg2(tr[idx],sz,sz,sz,sz);
			cg3(tr[idx],2);
		} else {
			node x=tr[idx];
			if(x.tag==1) tr[idx].tag=2;
			else if(x.tag==2) tr[idx].tag=1;
			else if(x.tag==3) tr[idx].tag=0;
			else tr[idx].tag=3;
			cg1(tr[idx],x.l1,x.r1,x.mx1);
			cg2(tr[idx],x.l0,x.r0,x.mx0,x.len-x.cnt1);
		}
		return ;
	}
	push_down(idx);
	int mid=(l+r)>>1;
	if(L<=mid) update(lc(idx),l,mid,L,R,tag);
	if(R>mid)  update(rc(idx),mid+1,r,L,R,tag);
	push_up(idx);
}
//void check() {
//	For(i,1,n) query_cnt(1,1,n,i,i);// puts("");
//}
signed main() {
//	freopen("qwq.in","r",stdin);
//	freopen("awa.out","w",stdout);
	in2(n,m);
	For(i,1,n) in1(a[i]);
	build(1,1,n);
	For(i,1,m) {
		int opt,l,r;
		in3(opt,l,r);
		l++,r++;
		if(opt==0) {
			update(1,1,n,l,r,1);
		} else if(opt==1) {
			update(1,1,n,l,r,2);
		} else if(opt==2) {
			update(1,1,n,l,r,3);
		} else if(opt==3) {
			cout<<query_cnt(1,1,n,l,r)<<'\n';
		} else cout<<query(1,1,n,l,r).mx1<<'\n';
//		check();
	}
}

标签:洛谷,idx,int,mid,read,query,SCOI2010,P2572,define
From: https://www.cnblogs.com/CodingGoat/p/18494337

相关文章

  • 20241022每日一题洛谷P1223
    普及洛谷P1223接水问题有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小第一行为一个整数n,第二行n个整数,第i个整数Ti表示第i个人的接水时间Ti输出两行,第一行为一种平均时间最短的排队顺......
  • 洛谷P3850 [TJOI2007] 书架 splay tree 模板题
    题目链接:https://www.luogu.com.cn/problem/P3850主要操作就是:插入+查询第k值。示例程序:#include<bits/stdc++.h>usingnamespacestd;constintmaxn=1.1e5+5,maxb=20;structNode{ints[2],p,sz;stringname;Node(){}Node(string_n......
  • 洛谷P2596 [ZJOI2006] 书架 题解 splay tree 模板题
    题目链接:https://www.luogu.com.cn/problem/P2596主要涉及的操作就是:找到某一个编号的点(这个操作可以不用splaytree维护)删除某个点将某一个点插入到最前面,最后面,或者某一个位置查询前序遍历为\(k\)的节点编号因为每次删除都会又把这个点加回去,所以可以复用\(n\)个......
  • 洛谷管理员语录(不完整)
    ......
  • P10724 [GESP202406 七级] 区间乘积,洛谷id:sxshm
    题解一、分析看看标签:数论,再看题目:完全平方。这不是质因数分解的标配吗?继续看数据范围:1≤ai......
  • 洛谷 P1197 [JSOI2008] 星球大战 做题记录
    我不会做摧毁,于是反着做,就变成了合并连通块,倒序加边即可,时间复杂度\(O((n+m)\alpha(n))\)。(大抵是吧点击查看代码#include<bits/stdc++.h>#definemem(aqwqawa,bqwqawa)memset((aqwqawa),(bqwqawa),sizeof(aqwqawa))#definem0(aqwqawa)memset((aqwqawa),0,sizeof(aqwqaw......
  • 洛谷题单指南-字符串-P4735 最大异或和
    原题链接:https://www.luogu.com.cn/problem/P4735题意解读:已知长度为n的数组a[],要在l~r范围找到一个p,使得a[p]^a[p+1]^...^a[n]^x最大,求这个最大的异或值。解题思路:1、利用前缀和将问题转化设s[]是a[]的前缀异或数组,要计算a中一段范围l~r的异或,可以借助于s由于s[r]=a[0]^a[......
  • 【洛谷 P1116】车厢重组 题解(模拟+冒泡排序)
    车厢重组题目描述在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他......
  • 【洛谷 P1116】车厢重组 题解(模拟+冒泡排序)
    车厢重组题目描述在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他......
  • 洛谷P3741 小果的键盘(Python)
    海阔凭鱼跃,天高任鸟飞。——宋·阮阅《诗话总龟前集》一、题目传送门https://www.luogu.com.cn/problem/P3741二、代码input()s=list(input().strip())ans="".join(s).count("VK")foriinrange(len(s)):ifs[i]=='V':s[i]='K'......