题目链接:戳我

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 项链工厂的更多相关文章

  1. BZOJ1493 [NOI2007]项链工厂

    未完待续... 终于改对了 热泪盈眶.jpg 错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误 #include<bits/stdc++ ...

  2. bzoj 1493: [NOI2007]项链工厂(线段树)

    1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1256  Solved: 545[Submit][Status] ...

  3. 数据结构(Splay平衡树): [NOI2007] 项链工厂

    [NOI2007] 项链工厂 ★★★   输入文件:necklace.in   输出文件:necklace.out   简单对比 时间限制:4 s   内存限制:512 MB [问题描述] T公司是一 ...

  4. bzoj1493[NOI2007]项链工厂 线段树

    1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1712  Solved: 723[Submit][Status] ...

  5. BZOJ_1493_[NOI2007]项链工厂_Splay

    BZOJ_1493_[NOI2007]项链工厂_Splay Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算 ...

  6. 1493: [NOI2007]项链工厂

    线段树. 真还就是个线段树.. 除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2.(这点没想到).. 我们用一个delta维护操作1,如果没有旋转就+k,不然就-k. 每次读入i和 ...

  7. BZOJ1493 NOI2007 项链工厂 线段树模拟

    提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...

  8. NOI2007项链工厂——sbTreap代码

    #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...

  9. 【BZOJ-1493】项链工厂 Splay

    1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1440  Solved: 626[Submit][Status] ...

随机推荐

  1. win10 Snipaste 截图软件

    安装教程:搜索 snipaste,网上可以直接下载 使用教程: 1)截图按钮:F1 2)粘贴按钮:F3

  2. 弹窗插件 layer

    官方网站 http://layer.layui.com/ Github 地址 https://github.com/sentsin/layer //在这里面输入任何合法的js语句 layer.open ...

  3. squoosh

    谷歌在线压缩图片

  4. RGB2GRAY 各种算法速度比较,整形乘法比查表法快!

    1.  查表法,外循环用 这种格式 :  //for(int j = 0; j != h; ++j)// for(int i = 0; i!=w;++i)//. for(int j = 0; j != ...

  5. mybatis 插入语句 返回自增长id方法

    背景:目前有个插入语句需要获取插入记录的id  因为id是自增长的,所以要在插入后返回这个id 错误1: mapper.xml: <!-- 新增 返回自增长id--> <insert ...

  6. 微信小程序iOS下拉白屏晃动,坑坑坑

    感觉ios的小程序每个页面都可以下拉出现白屏 有时页面带有滑动的属性会跟着晃动,体验不是很好 解决办法: 先禁止页面下拉 <config> { navigationBarTitleText ...

  7. 去重复的sql(Oracle)

    1.利用group by 去重复 2.可以利用下面的sql去重复,如下 1) select id,name,sex from (select a.*,row_number() over(partiti ...

  8. 对MySQL索引、锁及事务的简单分析

    一.索引的数据结构 1.二叉搜索树实现的索引 二叉搜索树如下图,它查找元素的时间复杂度为O(logn) 但如果经常出现增删操作,最后导致二叉搜索树变成线性的二叉树,这样它查找元素的时间复杂度就会变成O ...

  9. 配置Notepad++万能调试

    需求: 正常情况下 使用notepad++编辑修改一些网页或脚本文件,修改之后想要查看效果需要Ctrl+S保存,然后从文件目录中打开查看. 现在我想做的就是简化查看效果的流程,让notepad++实现 ...

  10. Eclipse配置Maven的本地仓库和阿里云镜像 加速Maven更新

    先确定自己电脑是否安装了Maven和安装位置,具体查询方法直接win+R键打开运行窗口,输入cmd打开dos窗口,再输入mvn -v即可查询安装的位置 拿到安装位置 D:\Applications\W ...