bzoj2120: 数颜色 &&bzoj2453: 维护队列

题目大意:

    你小时候玩过弹珠吗?

    小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N。为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少。当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色。             但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助。

题解:莫队或者分块

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define maxn 1000500
 7 using namespace std;
 8 int n,m,blo,num,q;
 9 int pre[maxn],c[maxn],b[maxn],last[maxn],pos[maxn];
10 int read()
11 {
12     int x=0; char ch; bool bo=0;
13     while (ch=getchar(),ch<‘0‘||ch>‘9‘) if (ch==‘-‘) bo=1;
14     while (x=x*10+ch-‘0‘,ch=getchar(),ch>=‘0‘&&ch<=‘9‘);
15     if (bo) return -x; return x;
16 }
17 void resort(int x)
18 {
19     int l=(x-1)*blo+1,r=min(x*blo,n);
20     for (int i=l; i<=r; i++) pre[i]=b[i];
21     sort(pre+l,pre+r+1);
22 }
23 int find(int x,int val)
24 {
25     int l=blo*(x-1)+1,r=min(blo*x,n); int first=l;
26     while (l<=r)
27     {
28         int mid=(l+r)>>1;
29         if (pre[mid]<val) l=mid+1;
30         else r=mid-1;
31     }
32     return l-first;
33 }
34 int ask(int l,int r)
35 {
36     int sum=0;
37     if (pos[l]==pos[r])
38     {
39         for (int i=l; i<=r; i++) if (b[i]<l) sum++;
40     }
41     else
42     {
43         for (int i=l; i<=pos[l]*blo; i++) if (b[i]<l) sum++;
44         for (int i=r; i>=(pos[r]-1)*blo+1; i--) if (b[i]<l) sum++;
45     }
46     for (int i=pos[l]+1; i<pos[r]; i++) sum+=find(i,l);
47     return sum;
48 }
49 void change(int x,int y)
50 {
51     for (int i=1; i<=n; i++) last[c[i]]=0;
52     c[x]=y;
53     for (int i=1; i<=n; i++)
54     {
55         int t=b[i];
56         b[i]=last[c[i]];
57         last[c[i]]=i;
58         if (t!=b[i]) resort(pos[i]);
59     }
60 }
61 void init()
62 {
63     n=read(); q=read();
64     blo=((int)sqrt(n));
65     for (int i=1; i<=n; i++) c[i]=read(),pos[i]=(i-1)/blo+1;
66     for (int i=1; i<=n; i++)
67     {
68         b[i]=last[c[i]];
69         last[c[i]]=i;
70     }
71     num=(n-1)/blo+1;
72     for (int i=1; i<=num; i++) resort(i);
73 }
74 void solve()
75 {
76     char ch[5]; int x,y;
77     for (int i=1; i<=q; i++)
78     {
79         scanf(" %s",ch+1); x=read(); y=read();
80         if (ch[1]==‘Q‘) printf("%d\n",ask(x,y));
81         else change(x,y);
82     }
83 }
84 int main()
85 {
86     init();
87     solve();
88 }

时间: 2024-10-21 10:36:44

bzoj2120: 数颜色 &&bzoj2453: 维护队列的相关文章

BZOJ 2120 数颜色&amp;2453 维护队列 [带修改的莫队算法]【学习笔记】

题意: 询问区间中不同颜色的个数,单点修改颜色 发现以前写的学习笔记没法看,于是重写一下(不就是会用latex了嘛) 额外维护一个当前修改操作执行到的时间 如果要进行某个查询操作,修改操作的时间必须移动到这个查询操作处 按照$(pos[l], pos[r], tim)$排序 令$S=N^{\frac{2}{3}}$, 有$N^{\frac{1}{3}}$块 $l$移动$N*N^{\frac{2}{3}}$次 $r$移动$N*N^{\frac{1}{3}}+N*N^{\frac{2}{3}}$次

[Bzoj2120]数颜色 (非正解 )(莫队)

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 6286  Solved: 2489[Submit][Status][Discuss] Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要干

BZOJ2120: 数颜色

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 1394  Solved: 516[Submit][Status] Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要干什么了吗? Inpu

[bzoj2453]维护队列_带修改莫队

维护队列 bzoj-2453 题目大意:给定一个n个数序列,支持查询区间数的种类数,单点修改.不强制在线. 注释:$1\le n,m\le 10^5$. 想法: 带修改莫队裸题. 如果没有修改操作的话,我们就正常按照莫队一样左右移动区间即可. 有了修改操作的话,我们把块变成$n^{\frac{2}{3}}$,关键字变成:左端点所在块.右端点所在块和时间戳. 然后暴力就行了. Code: #include <iostream> #include <cstdio> #include &

BZOJ2453: 维护队列

2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 183  Solved: 89[Submit][Status] Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会依据个人喜好,替换队列中某个弹珠的颜色.但是A还没有学过编程,且觉得头脑风暴太浪费脑力了,所以向你来寻求帮助. Inp

bzoj2120 数颜色 莫队 带修改

[bzoj2120]数颜色 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要干什么了吗? Input 第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数.第2行N个整数,分别代表初始画笔排中第i支画笔的颜色.第3行到第2+M行,每行分

BZOJ2120数颜色(带修改莫队)

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 7384  Solved: 2998[Submit][Status][Discuss] Description 墨 墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要

BZOJ2453维护队列&amp;&amp;BZOJ2120数颜色

2016-05-28 11:20:22 共同的思路:维护某种颜色上一次在哪里出现 BZOJ2453 http://www.lydsy.com/JudgeOnline/problem.php?id=2453 BZOJ2120 http://www.lydsy.com/JudgeOnline/problem.php?id=2120 #include<bits/stdc++.h> #define inf 1000000000 #define ll long long #define N 10005

BZOJ2120 数颜色 分块+二分法

题意:给定一个颜色序列,维护:1.单点修改  2.区间查询不同颜色的种数 题解: 定义f[i]为i左边第一个和i颜色相同的位置,用分块来维护f. 询问:看区间中有多少个位置的f[i]<l 更新:暴力枚举p左右最近的与p颜色相同的位置,更新即可 #include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #includ