P3939 数颜色

题目背景

大样例下发链接:http://pan.baidu.com/s/1c0LbQ2 密码:jigg

题目描述

小 C 的兔子不是雪白的,而是五彩缤纷的。每只兔子都有一种颜色,不同的兔子可能有 相同的颜色。小 C 把她标号从 1 到 n" role="presentation" style="position: relative;">nn 的n" role="presentation" style="position: relative;">nn 只兔子排成长长的一排,来给他们喂胡萝卜吃。 排列完成后,第 ii 只兔子的颜色是4ai" role="presentation" style="position: relative;">4ai4ai 。俗话说得好,“萝卜青菜,各有所爱”。小 C 发现,不同颜色的兔子可能有对胡萝卜的 不同偏好。比如,银色的兔子最喜欢吃金色的胡萝卜,金色的兔子更喜欢吃胡萝卜叶子,而 绿色的兔子却喜欢吃酸一点的胡萝卜……为了满足兔子们的要求,小 C 十分苦恼。所以,为 了使得胡萝卜喂得更加准确,小 C 想知道在区间 [lj,rj]" role="presentation" style="position: relative;">[lj,rj][lj,rj]里有多少只颜色为 cj" role="presentation" style="position: relative;">cjcj 的兔子。

不过,因为小 C 的兔子们都十分地活跃,它们不是很愿意待在一个固定的位置;与此同 时,小 C 也在根据她知道的信息来给兔子们调整位置。所以,有时编号为 xj" role="presentation" style="position: relative;">xjxj和 xj+1" role="presentation" style="position: relative;">xj+1xj+1的两 只兔子会交换位置。 小 C 被这一系列麻烦事给难住了。你能帮帮她吗?

输入输出格式

输入格式:

从标准输入中读入数据。 输入第 1 行两个正整数 n" role="presentation" style="position: relative;">nn , m" role="presentation" style="position: relative;">mm 。

输入第 2 行 n" role="presentation" style="position: relative;">nn 个正整数,第 i" role="presentation" style="position: relative;">ii 个数表示第 i" role="presentation" style="position: relative;">ii 只兔子的颜色 ai" role="presentation" style="position: relative;">aiai。

输入接下来 mm 行,每行为以下两种中的一种:

“1 lj rj cj1" role="presentation" style="position: relative;">1 lj rj cj11 lj rj cj1 ” :询问在区间[lj,rj]" role="presentation" style="position: relative;">[lj,rj][lj,rj]里有多少只颜色为cj" role="presentation" style="position: relative;">cjcj​ 的兔子;

“ 2 xj" role="presentation" style="position: relative;">2 xj2 xj”: xj" role="presentation" style="position: relative;">xjxj和 xj+1" role="presentation" style="position: relative;">xj+1xj+1两只兔子交换了位置。

输出格式:

输出到标准输出中。

对于每个 1 操作,输出一行一个正整数,表示你对于这个询问的答案。

输入输出样例

输入样例#1:

6 5

1 2 3 2 3 3

1 1 3 2

1 4 6 3

2 3

1 1 3 2

1 4 6 3

输出样例#1:

1

2

2

3

说明

【样例 1 说明】

前两个 1 操作和后两个 1 操作对应相同;在第三次的 2 操作后,3 号兔子和 4 号兔子

交换了位置,序列变为 1 2 2 3 3 3。

【数据范围与约定】

子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解 决一部分测试数据。 对于所有测试点,有 1≤lj&lt;rj≤n" role="presentation" style="position: relative;">1≤lj<rj≤n1≤lj<rj≤n,1≤xj&lt;n" role="presentation" style="position: relative;">1≤xj<n1≤xj<n 每个测试点的数据规模及特点如下表:



特殊性质 1:保证对于所有操作 1,有|rj−lj|≤20" role="presentation" style="position: relative;">|rj−lj|≤20|rj−lj|≤20或 |rj−lj|≤n−20" role="presentation" style="position: relative;">|rj−lj|≤n−20|rj−lj|≤n−20

特殊性质 2:保证不会有两只相同颜色的兔子。

好吧这又是一道水题,我可能是最近做数据结构做傻了,搞得连vector" role="presentation" style="position: relative;">vectorvector+二分这种技巧都搞忘了。没错,这道题标解就是vector" role="presentation" style="position: relative;">vectorvector+二分,但看到区间统计数的个数怎能不让人想到主席树呢?于是就有大佬对每种颜色建主席树跑过,但在我看来,这种方法和vector" role="presentation" style="position: relative;">vectorvector+二分的本质思想并没有区别,因此我另辟蹊径,自己yy" role="presentation" style="position: relative;">yyyy了一种做法(下来看了题解之后才发现自己又zz" role="presentation" style="position: relative;">zzzz了)。好吧我们对每个位置建一个主席树,然后主席树就成了前缀的形式,于是我们修改就与后面的前缀无关(因为从xj+1" role="presentation" style="position: relative;">xj+1xj+1到n" role="presentation" style="position: relative;">nn这些位置的每个数的权值仍然是不变的,这样的话操作2就变成了删除和插入操作的组合,不过貌似这样写会被卡常,本蒟蒻被卡了多次后乱改常数终于过了。事实证明switch" role="presentation" style="position: relative;">switchswitch的确快过if" role="presentation" style="position: relative;">ifif啊)

代码如下:

#include<bits/stdc++.h>
#define N 300005
using namespace std;
struct Node{int l,r,sum;}T[N*70];
int cnt=0,rt[N*70],n,m,col[N],siz=0;
inline void update(int &p,int last,int l,int r,int v,int tmp){
    p=++cnt,T[p].l=T[last].l,T[p].r=T[last].r;
    T[p].sum=T[last].sum+tmp;
    if(l==r)return;
    int mid=l+r>>1;
    if(v<=mid)update(T[p].l,T[last].l,l,mid,v,tmp);
    else update(T[p].r,T[last].r,mid+1,r,v,tmp);
}
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    return ans;
}
inline int query(int p,int l,int r,int v){
    if(l==r)return T[p].sum;
    int mid=l+r>>1;
    if(v<=mid)return query(T[p].l,l,mid,v);
    else return query(T[p].r,mid+1,r,v);
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;++i)update(rt[i],rt[i-1],1,300000,col[i]=read(),1);
    while(m--){
        int op=read(),l=read();
        switch(op){
            case 1:{
                int r=read(),c=read();
                printf("%d\n",query(rt[r],1,300000,c)-query(rt[l-1],1,300000,c));
                break;
            }
            default:{
                update(rt[l],rt[l],1,300000,col[l],-1);
                update(rt[l],rt[l],1,300000,col[l+1],1);
                col[l]^=col[l+1],col[l+1]^=col[l],col[l]^=col[l+1];
                break;
            }
        }
    }
    return 0;
}

2018.07.07 洛谷 P3939 数颜色(主席树)的更多相关文章

  1. 洛谷——P3939 数颜色(暴力vecotr+二分)

    P3939 数颜色 $vecotr$里二分就是好用,全是$STL$ 颜色数目比较少,可以对每一种颜色弄一个$vector$记录一下,查找$l,r$内颜色数为$x$的兔子数,直接在$G[x]$这个$ve ...

  2. 洛谷P3939 数颜色 二分查找

    正解:二分 解题报告: 传送门! 话说其实我开始看到这题想到的是分块,,, 但是显然不用这么复杂,,,因为仔细看下这题,会发现每次只改变相邻的兔子的位置 所以开个vector(或者开个数组也成QwQ( ...

  3. 洛谷P3939 数颜色(二分 vector)

    题意 题目链接 Sol 直接拿vector维护每种颜色的出现位置,然后二分一下. #include<bits/stdc++.h> using namespace std; const in ...

  4. [洛谷P3939]数颜色

    题目大意:有n个物品,每个物品有一个颜色.现在有两种操作:1.查询l-r内有多少颜色为c的物品并输出.2.将第x个物品和第x+1个交换.现在让你实现这些操作. 解题思路:首先一共有300000种颜色, ...

  5. [洛谷P3939]:数颜色(二分)

    题目传送门 题目描述 小$C$的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不同的兔子可能有相同的颜色.小$C$把她标号从$1$到$n$的$n$只兔子排成长长的一排,来给他们喂胡萝卜吃.排列 ...

  6. P3939 数颜色 线段树动态开点

    P3939 数颜色 线段树动态开点 luogu P3939 水.直接对每种颜色开个权值线段树即可,注意动态开点. #include <cstdio> #include <algori ...

  7. Bzoj2120/洛谷P1903 数颜色(莫队)

    题面 Bzoj 洛谷 题解 考虑对操作离线后分块处理询问操作(莫队算法),将询问操作按照编号分块后左端点第一关键字,右端点第二关键字排序(分块大小为\(n^{\frac 23}\)),对于每一个询问操 ...

  8. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

  9. [bzoj2120] [洛谷P1903] 数颜色

    Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜 ...

随机推荐

  1. java常用的Utils写法

    Utils: 获取年龄 属性文件获取 BeanCopy    分页 MapUtils 获取年龄: /** * 根据传入的日期计算年龄,因时间戳是从1970年开始计算的 * @param date * ...

  2. c++ static成员

    static 成员通常不能在类的定义体重初始化 有一种例外,const static成员可以在定义体内初始化,并且可以用于构造函数 将函数声明为const表示该函数不能修改其所属的对象

  3. win10 ubuntu双系统安装后无法引导进入ubuntu

    之前按照先装windows后装ubuntu的方式装的系统,都可以引导到ubuntu,无论是将ubuntu挂在到/boot在windows用easy BCD建立ubuntu引导,还是将ubuntu挂在到 ...

  4. xStream转换XML、JSON

        一. 简介 xStream可以很容易实现Java对象和xml文档互相转换, 可以修改某个特定的属性和节点名称,xStream提供annotation注解, 可以在JavaBean中完成对xml ...

  5. keras、 tensor flow 教程

    [keras]http://keras-cn.readthedocs.io/en/latest/getting_started/concepts/,[tensorflow] http://blog.c ...

  6. spring 中c3p0的优化配置

    jdbc.properties driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/testdb user=ro ...

  7. SpringCloud组件和概念介绍1

    一:什么是微服务(Microservice) 微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务.这些小的Web服务可以独立地编译及 ...

  8. Mysql InnoDB 数据更新 锁表

    一.数据表结构 1 2 3 4 5 6 7 8 9 10 CREATE TABLE `jx_attach` (   `attach_id` int(11) NOT NULL AUTO_INCREMEN ...

  9. easypanel api 文档

    easypanel api 文档 Easypanel的api通信安全码在easypanel的服务器设置处设置. 接口名称有: add_vh 创建空间和修改空间 update_vh 暂停空间和恢复空间 ...

  10. Android使用HTTPS进行IP直连握手失败问题(okHttp)

    为什么要使用ip直连这种方式去请求我们的服务器呢?这其实和国内运营伤有关,运营商有时为了利益会将你的域名劫持换成他人的域名,为了防止这种情况的发生通用的解决办法要么联系运营商要么就只能使用ip直连了. ...