NOI2007 项链工厂
题目链接:戳我
60pts
有一点容易写错的小细节:
比如说求全局的段数的时候,如果只有一种颜色,那么当左右端点相等时,就不要ans--了。
注意右端点小于左端点的情况。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define MAXN 2010
using namespace std;
int n,m,q;
int c[MAXN],tmp[MAXN];
namespace subtask1
{
inline void solve()
{
while(q--)
{
int x,y,k;
char s[3];
scanf("%s",s);
if(s[0]=='R')
{
scanf("%d",&x);
x%=n;
for(int i=1;i<=n;i++)
{
if(i+x<=n) tmp[i+x]=c[i];
else tmp[i+x-n]=c[i];
}
for(int i=1;i<=n;i++) c[i]=tmp[i];
}
else if(s[0]=='F')
{
int l=2,r=n;
while(l<r)
{
swap(c[l],c[r]);
l++,r--;
}
}
else if(s[0]=='S')
{
scanf("%d%d",&x,&y);
swap(c[x],c[y]);
}
else if(s[0]=='P')
{
scanf("%d%d%d",&x,&y,&k);
if(y>=x)
{
for(int i=x;i<=y;i++) c[i]=k;
}
if(y<x)
{
for(int i=x;i<=n;i++) c[i]=k;
for(int i=1;i<=y;i++) c[i]=k;
}
}
else if(strlen(s)>1&&s[0]=='C'&&s[1]=='S')
{
scanf("%d%d",&x,&y);
int cur_ans=0,i=x;
if(y<x) y+=n;
while(i<=y)
{
cur_ans++;
while(i<y&&c[i]==c[i+1]) i++;
i++;
}
printf("%d\n",cur_ans);
}
else
{
int cur_ans=0,i=1;
while(i<=n)
{
cur_ans++;
while(i<n&&c[i]==c[i+1]) i++;
i++;
}
if(cur_ans>1&&c[n]==c[1]) cur_ans--;
printf("%d\n",cur_ans);
}
for(int i=1;i<=n;i++) c[i+n]=c[i];
}
}
}
using namespace subtask1;
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&c[i]),c[i+n]=c[i];
scanf("%d",&q);
if(n<=1000&&q<=1000) subtask1::solve();
return 0;
}
100pts
如果没有翻转和旋转,很显然可以用线段树维护合并,更改和查询都是log的级别的。
但是旋转的话,我们可以通过记录一个变量,从而还原该操作在原先环中的位置。
然后观察翻转——通过绘图我们发现,翻转之后的环的顺时针移动翻转回来相当于原先的环的逆时针移动——所以我们就可以还原位置了。
我们把当前需要处理的位置,还原成它原本的位置上的编号,然后用线段树维护一下更新和查询就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define MAXN 500010
using namespace std;
int n,m,q,rev,kkk;
char s[5];
struct Node{int l,r,lc,rc,sum,tag;}t[MAXN<<2];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void push_up(int x)
{
t[x].lc=t[ls(x)].lc,t[x].rc=t[rs(x)].rc;
t[x].sum=t[ls(x)].sum+t[rs(x)].sum;
if(t[ls(x)].rc==t[rs(x)].lc) t[x].sum--;
}
inline void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
if(l==r)
{
t[x].sum=1;
int cur;
scanf("%d",&cur);
t[x].lc=t[x].rc=cur;
return;
}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
}
inline void f(int x,int k)
{
t[x].lc=t[x].rc=t[x].tag=k;
t[x].sum=1;
}
inline void push_down(int x)
{
if(t[x].tag)
{
f(ls(x),t[x].tag);
f(rs(x),t[x].tag);
t[x].tag=0;
}
}
inline void update(int x,int ll,int rr,int k)
{
int l=t[x].l,r=t[x].r;
if(ll<=l&&r<=rr)
{
f(x,k);
return;
}
push_down(x);
int mid=(l+r)>>1;
if(ll<=mid) update(ls(x),ll,rr,k);
if(mid<rr) update(rs(x),ll,rr,k);
push_up(x);
}
inline int query(int x,int ll,int rr)
{
int l=t[x].l,r=t[x].r;
if(ll==l&&r==rr) return t[x].sum;
push_down(x);
int mid=(l+r)>>1;
if(rr<=mid) return query(ls(x),ll,rr);
if(ll>mid) return query(rs(x),ll,rr);
else
{
int cur_ans=query(ls(x),ll,mid)+query(rs(x),mid+1,rr);
if(t[ls(x)].rc==t[rs(x)].lc) cur_ans--;
return cur_ans;
}
}
inline int pos(int x)
{
if(rev) x=n-x+2;
kkk%=n;
x-=kkk;
if(x>n) x-=n;
if(x<1) x+=n;
return x;
}
inline int calc(int x,int l,int r,int k)
{
if(l==r) return t[x].lc;
push_down(x);
int mid=(l+r)>>1;
if(k<=mid) return calc(ls(x),l,mid,k);
else return calc(rs(x),mid+1,r,k);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
build(1,1,n);
scanf("%d",&q);
while(q--)
{
int x,y,k;
scanf("%s",s);
if(s[0]=='R')
{
// printf("rotate\n");
scanf("%d",&x);
if(rev) kkk-=x;
else kkk+=x;
}
else if(s[0]=='F')
{
// printf("flip\n");
rev^=1;
}
else if(s[0]=='S')
{
// printf("swap\n");
scanf("%d%d",&x,&y);
x=pos(x),y=pos(y);
int c1=calc(1,1,n,x);
int c2=calc(1,1,n,y);
update(1,x,x,c2),update(1,y,y,c1);
}
else if(s[0]=='P')
{
// printf("paint\n");
scanf("%d%d%d",&x,&y,&k);
x=pos(x),y=pos(y);
if(rev) swap(x,y);
if(x<=y) update(1,x,y,k);
else update(1,x,n,k),update(1,1,y,k);
}
else if(strlen(s)>1&&s[0]=='C'&&s[1]=='S')
{
// printf("CS\n");
scanf("%d%d",&x,&y);
// printf("x=%d y=%d\n",x,y);
x=pos(x),y=pos(y);
// printf("x=%d y=%d\n",x,y);
if(rev) swap(x,y);
if(x<=y) printf("%d\n",query(1,x,y));
else
{
int cur_ans=query(1,x,n)+query(1,1,y);
if(t[1].rc==t[1].lc) cur_ans--;
printf("%d\n",cur_ans);
}
}
else
{
// printf("C\n");
int cur_ans=query(1,1,n);
if(cur_ans>1&&t[1].rc==t[1].lc) cur_ans--;
printf("%d\n",cur_ans);
}
}
return 0;
}
NOI2007 项链工厂的更多相关文章
- BZOJ1493 [NOI2007]项链工厂
未完待续... 终于改对了 热泪盈眶.jpg 错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误 #include<bits/stdc++ ...
- bzoj 1493: [NOI2007]项链工厂(线段树)
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1256 Solved: 545[Submit][Status] ...
- 数据结构(Splay平衡树): [NOI2007] 项链工厂
[NOI2007] 项链工厂 ★★★ 输入文件:necklace.in 输出文件:necklace.out 简单对比 时间限制:4 s 内存限制:512 MB [问题描述] T公司是一 ...
- bzoj1493[NOI2007]项链工厂 线段树
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1712 Solved: 723[Submit][Status] ...
- BZOJ_1493_[NOI2007]项链工厂_Splay
BZOJ_1493_[NOI2007]项链工厂_Splay Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算 ...
- 1493: [NOI2007]项链工厂
线段树. 真还就是个线段树.. 除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2.(这点没想到).. 我们用一个delta维护操作1,如果没有旋转就+k,不然就-k. 每次读入i和 ...
- BZOJ1493 NOI2007 项链工厂 线段树模拟
提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...
- NOI2007项链工厂——sbTreap代码
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...
- 【BZOJ-1493】项链工厂 Splay
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1440 Solved: 626[Submit][Status] ...
随机推荐
- java:线上问题排查常用手段(转)
出处:java:线上问题排查常用手段 一.jmap找出占用内存较大的实例 先给个示例代码: import java.util.ArrayList; import java.util.List; imp ...
- Java反射的理解(六)-- 通过反射了解集合泛型的本质
Java反射的理解(六)-- 通过反射了解集合泛型的本质 上述写了那么多,我们可能会有个疑问,为什么要用反射,步骤比我们常规的加载类操作复杂多了,别急,这个问题我最后才解答,我们先来了解集合泛型的本质 ...
- Dev-C++的一些使用技巧快捷键
最近开始用Dev-C++在Window下编程,感觉Dec-C++是一款挺不错的C++编译器.下载地址http://www.duote.com/soft/9830.html .现总结一些使用技巧: 1. ...
- Spingboot+Mybatis+Oracle项目配置
配置过程参考: 项目创建:http://how2j.cn/k/springboot/springboot-eclipse/1640.html 集成Mybatis使用Oracle:https://www ...
- PMP - 风险识别之风险登记册
目录 PMP - 风险识别之风险登记册 1. 风险登记册 1.1 已识别风险的清单 1.2 潜在风险责任人 1.3 潜在风险应对措施清单 2. 相关习题 2.1 风险发生的时候,要实施 风险登记册 上 ...
- git 查看当前仓库地址以及设置新的仓库地址
1.查看当前仓库地址 git remote show origin 2.设置新的仓库地址 1.先登录 gitlab 查看当前仓库地址: 执行修改地址命令 git remote set-url orig ...
- input 禁止输入特殊字符
方式一:拿到value值以后 在你传递之前处理 function stripscript(value) { var pattern = new RegExp("[`~!@#$^&*( ...
- 1 SQL SERVER 实现字符串分割成table的方法
CREATE FUNCTION [dbo].[fn_SplitStringToTable] ( @p_Input VARCHAR(MAX), @p_Delimeter CHAR() = ',' ) R ...
- Spring自定义标签的实现
首先 简单写下 spring xml解析的过程 通过一段简单的 调用spring代码开始 public static void main(String[] args) { ApplicationCon ...
- javascript 元编程之 method_missing
javascript 元编程之 method_missing 引言 要说元编程 ruby 中技巧太多了,今天来写的这个技术也来自于 ruby 中的灵感. method_missing 这个在 ruby ...