洛谷2253 好一个一中腰鼓!
2018-03-17 12:34
183 查看
题目:好一个一中腰鼓!
思路:单点修改的线段树。每一个节点维护当前区间的长度、最左和最右鼓的颜色和最长的交错前缀长和后缀长。注意边界问题。
代码:#include<bits/stdc++.h>
using namespace std;
#define maxn 20000
struct Node {
int len;
int x,y;
int lw,rw;
};
int n,m;
Node tr[maxn*4+5];
void make_tree(int o,int l,int r) {
tr[o].len=r-l+1,tr[o].x=tr[o].y=tr[o].lw=tr[o].rw=1;
if(r==l) return ;
int mid=l+(r-l)/2;
make_tree(o*2,l,mid),make_tree(o*2+1,mid+1,r);
}
int p;
void update(int o,int l,int r) {
if(p<l||p>r) return ;
if(l==r) {
tr[o].x^=1,tr[o].y^=1;
return ;
}
int mid=l+(r-l)/2;
int lc=o*2,rc=o*2+1;
update(lc,l,mid),update(rc,mid+1,r);
tr[o].x=tr[lc].x,tr[o].y=tr[rc].y;
tr[o].lw=tr[lc].lw,tr[o].rw=tr[rc].rw;
if(tr[lc].y^tr[rc].x) {
if(tr[lc].lw==tr[lc].len) tr[o].lw+=tr[rc].lw;
if(tr[rc].rw==tr[rc].len) tr[o].rw+=tr[lc].rw;
}
return ;
}
int query(int o,int l,int r){ //注意不能在updata时直接处理询问
if(l==r) return 1;
int mid=l+(r-l)/2;
int lc=o*2,rc=o*2+1;
int ans1=query(lc,l,mid),ans2=query(rc,mid+1,r);
return max(max(ans1,ans2),(tr[lc].y^tr[rc].x)?tr[rc].lw+tr[lc].rw:1);
}
int main() {
scanf("%d%d",&n,&m);
make_tree(1,1,n);
for(int i=1; i<=m; i++) {
scanf("%d",&p);
update(1,1,n);
int ans=query(1,1,n);
printf("%d\n",ans);
}
return 0;
}
思路:单点修改的线段树。每一个节点维护当前区间的长度、最左和最右鼓的颜色和最长的交错前缀长和后缀长。注意边界问题。
代码:#include<bits/stdc++.h>
using namespace std;
#define maxn 20000
struct Node {
int len;
int x,y;
int lw,rw;
};
int n,m;
Node tr[maxn*4+5];
void make_tree(int o,int l,int r) {
tr[o].len=r-l+1,tr[o].x=tr[o].y=tr[o].lw=tr[o].rw=1;
if(r==l) return ;
int mid=l+(r-l)/2;
make_tree(o*2,l,mid),make_tree(o*2+1,mid+1,r);
}
int p;
void update(int o,int l,int r) {
if(p<l||p>r) return ;
if(l==r) {
tr[o].x^=1,tr[o].y^=1;
return ;
}
int mid=l+(r-l)/2;
int lc=o*2,rc=o*2+1;
update(lc,l,mid),update(rc,mid+1,r);
tr[o].x=tr[lc].x,tr[o].y=tr[rc].y;
tr[o].lw=tr[lc].lw,tr[o].rw=tr[rc].rw;
if(tr[lc].y^tr[rc].x) {
if(tr[lc].lw==tr[lc].len) tr[o].lw+=tr[rc].lw;
if(tr[rc].rw==tr[rc].len) tr[o].rw+=tr[lc].rw;
}
return ;
}
int query(int o,int l,int r){ //注意不能在updata时直接处理询问
if(l==r) return 1;
int mid=l+(r-l)/2;
int lc=o*2,rc=o*2+1;
int ans1=query(lc,l,mid),ans2=query(rc,mid+1,r);
return max(max(ans1,ans2),(tr[lc].y^tr[rc].x)?tr[rc].lw+tr[lc].rw:1);
}
int main() {
scanf("%d%d",&n,&m);
make_tree(1,1,n);
for(int i=1; i<=m; i++) {
scanf("%d",&p);
update(1,1,n);
int ans=query(1,1,n);
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- 洛谷P2253 好一个一中腰鼓!
- 洛谷 P2253 好一个一中腰鼓 --线段树
- P2253 好一个一中腰鼓!
- 关于“必须至少有一个对象实现 IComparable。”问题的另一中错误 解法
- 又是一个莫名的WA【极其不爽】洛谷 [USACO1.2]方块转换
- 洛谷P2256 一中运动会之百米跑
- 把一个一中的字段更新另一个表中的t-sql
- 洛谷P1332 血色先锋队(emmm一个词语概括:脑洞很大)
- 编程作业160 页 第5题 使用(接口)设计一个动物声音"模拟器",希望模拟器可以模拟许多动物声音
- SpringMVC(一):搭建一个SpringMVC helloword项目
- 个人解决的一个IDEA项目中不能引用pom文件中添加的依赖问题
- 火狐浏览器单击链接总是在一个新的标签页打开的设置方法
- 【Unity优化】构建一个拒绝GC的Lis
- 做一个串行执行的存储过程
- jupyter notebook一个很好用的Python笔记本
- linux怎么用一个命令行统计出给定目录中有多少个子目录
- jquery操作checkbox方法(全选、全不选、至少选择一个、选择值/文本)
- 一个重要的http协议头标:X-Forwarded-For
- 洛谷P3388 【模板】割点(割顶)
- 用python的cmd模块写一个简单的shell