题目链接:戳我

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. Codeforces 1237F. Balanced Domino Placements

    传送门 很妙的题 首先先考虑一个简化的问题,现在有一行格子让你填 你要么填一格 要么填两格 有的格子不让你填 问你填了 $a$ 个一格和填了 $b$ 个两格有多少种方案 那么显然先只考虑放两格的方案, ...

  2. 在react项目当中做导航守卫

    距离上一篇文章,似乎已经过去好久了. 确实是最近相对忙了一点,本身是用vue重构之前一个传统的项目,就自己一个人写.而且,在稍微闲暇之余,想着同时用react也重构一遍,也算是对react的学习吧!毕 ...

  3. Fullscreen API:全屏操作

    function launchFullscreen(element) { if(element.requestFullscreen) { element.requestFullscreen(); } ...

  4. inline元素、block元素

    inline元素 不会独占一行,相邻的行内元素会排列在同一行内,直到一行排不下才会换行 高.行高.以及外边距和内边距不可改变 宽度就是它的文字或图片的宽度,不可改变,随元素内容变化而变化 内联元素只能 ...

  5. java自定义excel

    文件下载 本文主要介绍spring boot环境下,利用Apache POI操作Excel,实现Excel文件的在线下载. 首先,我们在这里介绍一下关于ApachePOI中关于HSSF,XSSF和SX ...

  6. winfrom 点击按钮button弹框显示颜色集

    1.窗体托一个按钮button: 2.单击事件: private void btnForeColor_Click(object sender, EventArgs e) { using (ColorD ...

  7. JS基础_打印出1-100之间所有的质数

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 打包JavaFX11桌面应用程序

    打包JavaFX11桌面应用程序 这是JavaFX系列的第二弹,第一弹在这里 在第一弹中,我们使用的是OpenJDK8,但是OpenJDK8和Oracle Java JDK不一样,它没有内置JavaF ...

  9. 一个小时前,美国主流媒体,头条,谷歌两位创始人突然宣布退下来,把万亿美元的帝国交给Sundar Pichai

    一个小时前,美国各大主流媒体头条,谷歌两位创始人,放弃了万亿美元的帝国控制权,交给了CEO Sundar Pichai.  ​​​

  10. centos7上的firewalld 的使用

    #centos7上的firewalld 的使用 一.firewalld的基本启动关闭命令 启动服务------systemctl start firewalld 关闭服务------systemctl ...