洛谷 P2253 好一个一中腰鼓 --线段树

P2253 好一个一中腰鼓 --线段树

题目背景

话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来。

Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢哗者,遂与外人间隔。”

题目描述

设想一下,腰鼓有两面,一面是红色的,一面是白色的。初二的苏大学神想给你这个oier出一道题。假设一共有N(1<=N<=20,000)个同学表演,表演刚开始每一个鼓都是红色面朝向观众,舞蹈老师会发出M(1<=M<=20,000)个指令,如果指令发给第i个表演的同学,这位同学就会把腰鼓反过来,如果腰鼓之前是红色面朝向观众的,那么就会变成白色面朝向观众,反之亦然。那么问题来了(!?),在老师每一次发出指令后,找到最长的连续的一排同学,满足每相邻的两个手中的腰鼓朝向观众的一面互不相同,输出这样一排连续的同学的人数。

输入输出格式

输入格式:

第一行有两个整数, 分别为表演的同学总数N, 和指令总数M。

之后M行, 每行有一个整数i: 1<=i<=N, 表示舞蹈老师发出的指令。

输出格式:

输出有M行, 其中每i行有一个整数.

表示老师的第i条指令发出之后, 可以找到的满足要求的最长连续的一排表演同学有多长?

输入输出样例

输入样例#1:

6 2
2
4

输出样例#1:

3
5

说明

Huangc温馨提示:其实数据根本没你想象的那么大。。。[坏笑]、、

 1 /*
 2     在区间维护三个值
 3     一个是le 代表从左端点开始向右的最大01序列
 4     一个是ri 代表从右端点开始向左的最大01序列
 5     一个是all  代表整个区间最大的01序列
 6     xl 代表区间左端点的值
 7     xr 代表区间右端点的值
 8 */
 9 #include <cstdio>
10 #include <ctype.h>
11
12 const int MAXN=20010;
13
14 int n,m;
15
16 struct node {
17     int l,r;
18     int xl,xr;
19     int le,ri,all;
20 };
21 node t[MAXN<<2];
22
23 inline void read(int&x) {
24     int f=1;register char c=getchar();
25     for(x=0;!isdigit(c);c==‘-‘&&(f=-1),c=getchar());
26     for(;isdigit(c);x=x*10+c-48,c=getchar());
27     x=x*f;
28 }
29
30 inline int max(int a,int b) {
31     return a<b?b:a;
32 }
33
34 inline void up(int now) {
35     t[now].xl=t[now<<1].xl;t[now].xr=t[now<<1|1].xr;
36     t[now].le=t[now<<1].le;t[now].ri=t[now<<1|1].ri;
37     t[now].all=max(t[now<<1].all,max(t[now<<1|1].all,max(t[now<<1|1].le,t[now<<1].ri)));
38     if(t[now<<1].xr==t[now<<1|1].xl^1) {
39         t[now].all=max(t[now].all,t[now<<1].ri+t[now<<1|1].le);
40         if(t[now<<1].le==(t[now<<1].r-t[now<<1].l+1))
41           t[now].le=max(t[now].le,t[now<<1].le+t[now<<1|1].le);
42         if(t[now<<1|1].ri==(t[now<<1|1].r-t[now<<1|1].l+1))
43           t[now].ri=max(t[now].ri,t[now<<1|1].ri+t[now<<1].ri);
44     }
45     return;
46 }
47
48 void build_tree(int now,int l,int r) {
49     t[now].l=l,t[now].r=r;
50     if(l==r) {
51         t[now].xl=t[now].xr=1;
52         t[now].le=t[now].ri=t[now].all=1;
53         return;
54     }
55     int mid=(l+r)>>1;
56     build_tree(now<<1,l,mid);
57     build_tree(now<<1|1,mid+1,r);
58     up(now);
59 }
60
61 void modify(int now,int pos) {
62     if(t[now].l==t[now].r) {
63         t[now].xl=t[now].xr=t[now].xl^1;
64         return;
65     }
66     int mid=(t[now].l+t[now].r)>>1;
67     if(pos<=mid) modify(now<<1,pos);
68     else modify(now<<1|1,pos);
69     up(now);
70 }
71
72 int hh() {
73     int x;
74     read(n);read(m);
75     build_tree(1,1,n);
76     for(int i=1;i<=m;++i) {
77         read(x);
78         modify(1,x);
79         printf("%d\n",t[1].all);
80     }
81     return 0;
82 }
83
84 int sb=hh();
85 int main() {;}

代码

时间: 2024-12-30 00:06:14

洛谷 P2253 好一个一中腰鼓 --线段树的相关文章

洛谷 P2253 好一个一中腰鼓!

题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:“忽一人大呼:‘好一个安塞腰鼓!’满座寂然,无敢哗者,遂与外人间隔.” 题目描述 设想一下,腰鼓有两面,一面是红色的,一面是白色的.初二的苏大学神想给你这个oier出一道题.假设一共有N(1<=N<=20,000)个同学表演,表演刚开始每一个鼓都是红色面朝向观众,舞蹈老师会发出M(1<=M<=20,000)个指令,如果指令发给第i个

洛谷P2253 好一个一中腰鼓!

题目背景 话说我大一中的运动会就要来了,据本班同学剧透(其实早就知道了),我萌萌的初二年将要表演腰鼓[喷],这个无厘头的题目便由此而来. Ivan乱入:"忽一人大呼:'好一个安塞腰鼓!'满座寂然,无敢哗者,遂与外人间隔." 题目描述 设想一下,腰鼓有两面,一面是红色的,一面是白色的.初二的苏大学神想给你这个oier出一道题.假设一共有N(1<=N<=20,000)个同学表演,表演刚开始每一个鼓都是红色面朝向观众,舞蹈老师会发出M(1<=M<=20,000)个指令

线段树 P2253 好一个一中腰鼓!

传送门 不得不说 这真是一道不错的线段树的题目 这一道题的大意就是说 一开始所有的状态均为0 会有m次指令 每一次可以把一个点的状态进行更改 原来是0就变成1 原来是1就变成0 为了锻炼代码能力 我决定还是中规中矩地写线段树 这一道题还规定了一种串  就是0和1间隔交替 (比如010101  101 01010) 你每一次更改之后 要求出所有的点组成的序列中最长的连续“01”串 那么这一道题如果用线段树来做 转移会稍微复杂一点 我们定义sum为当前区间最长的01串 lsum为当前区间最长的前缀0

P2253 好一个一中腰鼓!

P2253 好一个一中腰鼓! 本蒟蒻第一次用线段树做连续最长子段 线段树是将一个大区间二分成两个小区间,通过递归解决两个小区间的问题,然后合并.得到大区间的解. 类比一下分治法求单个最长连续子段. 每次也都是将一个大区间分成两个小区间.分别解决完小区间后.将小区间合并,从分界点左右遍历.暴力的求连续子序列的长度. 然后将两个小区间分别作为一个区间求解的最优值和从分界点的连续子段长度比较,然后就得到了这个大区间的最长连续子段的长度. 可是,如果在线段树中呢?每次从分界点暴力的求时间复杂度太高. 那

洛谷P3434 [POI2006]KRA-The Disks(线段树)

洛谷题目传送门 \(O(n)\)的正解算法对我这个小蒟蒻真的还有点思维难度.洛谷题解里都讲得很好. 考试的时候一看到300000就直接去想各种带log的做法了,反正不怕T...... 我永远只会有最直观的思路(最差的程序效率) 题目相当于每次让我们找区间\([1,las-1]\)中上数第一个比当前盘子半径小的位置(las为上一次盘子掉到的位置)于是用线段树无脑搞一下,维护区间最小值,每次找这个位置,能往左跳就往左,不能的话再往右,当然如果超过了las-1就不用找了,直接放在las上面(相当于la

【洛谷P3372】【模板】线段树 1

题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k 操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和 输出格式: 输出包含若干行整

【原创】洛谷 LUOGU P3373 【模板】线段树2

P3373 [模板]线段树 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别表示该数列数字的个数.操作的总个数和模数. 第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值. 接下来M行每行包含3或4个整数,表示一个操作,具体如下: 操作1: 格式:1 x y k 含义:将区间[x,y]内每个数乘上k 操作2: 格式:2 x

洛谷P3128 [USACO15DEC]最大流Max Flow [树链剖分]

题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his barn (), conveniently numbered . Each pipe connects a pair of stalls, and all stalls are connected to each-other via paths of pipes. FJ is pumping milk

【P2253】 好一个一中腰鼓!

Description 给定一个01子串和操作数,每次操作可以使一个元素0变为1, 1变为0,求区间最长连续相邻不相等的长度 Solution 对于最长连续不相等,我们可以用几个量来维护,为: 1  lf 从左边开始的最长连续相邻不相等最大长度 2 rf 从右边开始的最长连续相邻不相等最大长度 3 mf 内部的最长连续相邻不相等最大长度 所以,最长的长度为max(tr[1].lf, tr[1].rf, tr[1].mf),对于每一个变量我们可以这样维护 tr[x].lf = max(tr[x <