• 【BZOJ1493】【NOI2007】项链工厂(线段树)


    【BZOJ1493】项链工厂(线段树)

    题面

    BZOJ
    洛谷

    Description

    T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。

    最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。该项链自助生产系

    统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的

    项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能

    帮助T公司编写一个软件模拟系统吗?一条项链包含 N 个珠子,每个珠子的颜色是 1,2,…,c 中的一种。项链

    被固定在一个平板上,平板的某个位置被标记位置 1 ,按顺时针方向其他位置被记为 2,3,…,N。

    img

    你将要编写的软件系统应支持如下命令:

    img

    Input

    输入文件第一行包含两个整数 N,c ,分别表示项链包含的珠子数目以及颜色数目。

    第二行包含 N 个整数,x1,x2,…,xn ,表示从位置 1 到位置 N 的珠子的颜色,1≤xi≤c 。

    第三行包含一个整数 Q ,表示命令数目。接下来的 Q 行每行一条命令,如上文所述。N≤500000 ,Q≤500000,c≤1000

    Output

    对于每一个 C 和 CS 命令,应输出一个整数代表相应的答案。

    Sample Input

    5 3
    1 2 3 2 1
    4
    C
    R 2
    P 5 5 2
    CS 4 1

    Sample Output

    4
    1

    HINT

    注意旋转命令旋转“珠子”但不改变“位置”的编号,而反转命令始终以位置 1 为对称轴。例如当 N=10 时,项

    链上的位置编号如图1:

    img

    但注意此时项链上的位置编号仍然如图1所示,于是翻转的对称轴不变。因而再执行一次“F”命令时,项链的颜色

    如图4所示。

    2. 关于CountSegment命令CS命令表示查询一个“线段”中有多少个“部分”。尤其注意当查询的长度

    等于 N 时,我们仍然将查询部分作为“线段”理解。例如在图4所示的情况中,执行“CS 1 10”命令,查询从位

    置 1 开始到位置 10 结束的这个长度为 10 的线段中有多少个“部分”,于是得到返回值 3 。与之形成对照的是

    ,若执行“C”命令,返回值则为 2

    题解

    先不考虑翻转之类的操作
    剩下的操作很显然就是一个线段树,
    具体的就是和SDOI染色那道题目是一样的

    考虑翻转和旋转操作
    一个是顺时针旋转,如果不存在翻转操作
    我们显然可以通过记录顺时针旋转的次数来还原当前的一号位置
    多了一个翻转
    仔细观察,就是把顺时针变为了逆时针而已
    所以直接乘个负号,额外加一个标记就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define lson (now<<1)
    #define rson (now<<1|1)
    #define MAX 555555
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Node
    {
    	int lc,rc;
    	int s,tag;
    }t[MAX<<2];
    void pushup(int now)
    {
    	t[now].lc=t[lson].lc;t[now].rc=t[rson].rc;
    	t[now].s=t[lson].s+t[rson].s-(t[lson].rc==t[rson].lc);
    }
    void Build(int now,int l,int r)
    {
    	if(l==r){t[now].s=1;t[now].lc=t[now].rc=read();return;}
    	int mid=(l+r)>>1;
    	Build(lson,l,mid);Build(rson,mid+1,r);
    	pushup(now);
    }
    void pushdown(int now)
    {
    	if(!t[now].tag)return;
    	int c=t[now].tag;
    	t[lson].lc=t[lson].rc=t[rson].lc=t[rson].rc=c;
    	t[lson].tag=t[rson].tag=c;
    	t[lson].s=t[rson].s=1;
    	t[now].tag=0;
    }
    void Modify(int now,int l,int r,int L,int R,int c)
    {
    	if(L<=l&&r<=R){t[now].lc=t[now].rc=t[now].tag=c;t[now].s=1;return;}
    	pushdown(now);int mid=(l+r)>>1;
    	if(L<=mid)Modify(lson,l,mid,L,R,c);
    	if(R>mid)Modify(rson,mid+1,r,L,R,c);
    	pushup(now);
    }
    int Getcolor(int now,int l,int r,int p)
    {
    	if(l==r)return t[now].lc;
    	pushdown(now);int mid=(l+r)>>1;
    	if(p<=mid)return Getcolor(lson,l,mid,p);
    	else return Getcolor(rson,mid+1,r,p);
    }
    int Query(int now,int l,int r,int L,int R)
    {
    	if(l==L&&r==R)return t[now].s;
    	pushdown(now);int mid=(l+r)>>1;
    	if(R<=mid)return Query(lson,l,mid,L,R);
    	if(L>mid)return Query(rson,mid+1,r,L,R);
    	return Query(lson,l,mid,L,mid)+Query(rson,mid+1,r,mid+1,R)-(t[lson].rc==t[rson].lc);
    }
    int Rev,K,n;
    int Pos(int x)
    {
    	if(Rev)x=n-x+2;
    	x-=K;
    	while(x<1)x+=n;while(x>n)x-=n;
    	return x;
    }
    int main()
    {
    	freopen("yyb.in","r",stdin);
    	n=read();int C=read();Build(1,1,n);
    	int Q=read();char opt[5];
    	while(Q--)
    	{
    		scanf("%s",opt);
    		if(opt[0]=='R')
    		{
    			if(Rev)K-=read();
    			else K+=read();
    			while(K<1)K+=n;while(K>n)K-=n;
    		}
    		else if(opt[0]=='F')Rev^=1;
    		else if(opt[0]=='S')
    		{
    			int x=read(),y=read();x=Pos(x);y=Pos(y);
    			int c1=Getcolor(1,1,n,x),c2=Getcolor(1,1,n,y);
    			Modify(1,1,n,x,x,c2);Modify(1,1,n,y,y,c1);
    		}
    		else if(opt[0]=='P')
    		{
    			int x=read(),y=read(),c=read();
    			x=Pos(x);y=Pos(y);if(Rev)swap(x,y);
    			if(x<=y)Modify(1,1,n,x,y,c);
    			else Modify(1,1,n,x,n,c),Modify(1,1,n,1,y,c);
    		}
    		else if(opt[0]=='C'&&opt[1]=='S')
    		{
    			int x=read(),y=read();
    			x=Pos(x);y=Pos(y);if(Rev)swap(x,y);
    			if(x<=y)printf("%d
    ",Query(1,1,n,x,y));
    			else printf("%d
    ",Query(1,1,n,x,n)+Query(1,1,n,1,y)-(t[1].lc==t[1].rc));
    		}
    		else printf("%d
    ",max(1,Query(1,1,n,1,n)-(t[1].lc==t[1].rc)));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    git init 与 git init --bare 区别
    python_集合_笔记
    git笔记
    screen命令
    python的and和or优先级
    计算机语言的发展史
    python3颜色输出
    mysql_windows解压包安装
    那些经常不开心的上班族
    mysql主从搭建
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8697838.html
Copyright © 2020-2023  润新知