首页 > 其他分享 >P1903 [国家集训队] 数颜色 / 维护队列 题解

P1903 [国家集训队] 数颜色 / 维护队列 题解

时间:2023-06-16 22:33:54浏览次数:40  
标签:opt ++ 题解 P1903 int cnt2 cnt1 -- 国家集训队

一、题目描述:

  给你一个长度为 $n$ 的序列 $a$ , 你需要进行 $m$ 次操作。

  $类型\ 1\ : 将第\ x\ 个元素的值修改为\ v\ 。$

  $类型\ 2\ : 求区间\ l\ 到\ r\ 中有多少种数字。$

  数据范围:$1 \le n,m \le 1333333,所有数字 \le 1\times 10^6$


 二、解题思路:

  带修莫队:(思路当然也不是我想出来的$qwq$)

  加一维时间轴,感觉有点抽象,但还是可以理解。

  当块长取 $n^{\frac{2}{3}}$ 时时间复杂度最优,$OI\ WiKi$ 上有详细的解释。

  时间复杂度 $n^{\frac{5}{3}}$。轻微卡常


 三、完整代码:

 1 #include<cmath>
 2 #include<iostream>
 3 #include<algorithm>
 4 #define N 150000
 5 #define K 1000010
 6 using namespace std;
 7 char opt;
 8 int cnt1,cnt2;
 9 int n,m,l=1,r,M,sum;
10 int c[N],ans[N],cnt[K];
11 struct Query{
12     int L,R,T,id;
13     bool operator < (const Query &t)const{
14         if(L/M!=t.L/M)    return L<t.L;
15         if(R/M!=t.R/M)    return R<t.R;
16         return T<t.T;
17     }
18 }a[N];
19 struct Modify{
20     int p,val;
21 }b[N];
22 void upt(int v,int f)
23 {
24     cnt[v]+=f;
25     if(f>0&&cnt[v]==1)    sum++;
26     if(f<0&&cnt[v]==0)    sum--;
27 }
28 void Change(int t)
29 {
30     if(l<=b[t].p&&b[t].p<=r)
31         upt(b[t].val,1),upt(c[b[t].p],-1);
32     swap(b[t].val,c[b[t].p]);
33 }
34 int main()
35 {
36     ios::sync_with_stdio(false);
37     cin.tie(0);cout.tie(0);
38     cin>>n>>m;
39     M=pow(n,2.0/3.0);
40     for(int i=1;i<=n;i++)
41         cin>>c[i];
42     for(int i=1;i<=m;i++)
43     {
44         cin>>opt;
45         if(opt=='Q')
46         {
47             cnt1++;
48             cin>>a[cnt1].L>>a[cnt1].R;
49             a[cnt1].id=cnt1,a[cnt1].T=cnt2;
50         }
51         if(opt=='R')
52             cnt2++,cin>>b[cnt2].p>>b[cnt2].val;
53     }
54     sort(a+1,a+1+cnt1);
55     for(int i=1,t=0;i<=cnt1;i++)
56     {
57         while(t<a[i].T)    Change(++t);
58         while(t>a[i].T)    Change(t--);
59         while(l>a[i].L)    upt(c[--l],1);
60         while(r<a[i].R)    upt(c[++r],1);
61         while(l<a[i].L)    upt(c[l++],-1);
62         while(r>a[i].R)    upt(c[r--],-1);
63         ans[a[i].id]=sum;
64     }
65     for(int i=1;i<=cnt1;i++)
66         cout<<ans[i]<<'\n';
67     return 0;
68 }

四、写题心得:

  第一道带修莫队,纪念一下。收获经验如下:

  $1、分块的预处理方式:笑死,其实根本不用预处理好吧,预处理在你心里就可以了。=> Exp++!$

  $2、cin,cout\ 的时候不要在对数据\ ++,--,多半会出问题,以后都单独写出来比较好。=> Exp++!$

  $3、一些漂亮的写法可能是存在漏洞的,先正常写,A\ 掉了再改也不迟。=> Exp++!$

  $4、inline\ 函数卡常效果真的很明显,7s\ 变到\ 4s。=> Exp++!$

标签:opt,++,题解,P1903,int,cnt2,cnt1,--,国家集训队
From: https://www.cnblogs.com/yhy-trh/p/P1903.html

相关文章

  • CF1205C Palindromic Paths 题解
    很好的一道题,思路自然,步骤清晰,结论好猜。唯一的缺点可能只是我赛时没有看到。构造可行解看到题目,也许我们很快就能想出一个做法:每次询问\((i,j,i+1,j)\),每行第一个额外询问\((i,j,i+1,j)\),这样询问总共\(n^2-1\)次即可。当我们怀疑看错题目重新检查时发现了被微软翻译......
  • 「ULSG-1」泡水的铅筒 题解
    题目传送门题目描述一个圆锥放入一个长方体水池中,无水溢出,求长方体液面高度的最大、最小值。解题思路如果这个题只有一个数据点,此数据点只有一组数据,那这就是一道初中填空题()先考虑\(h1\)的最小值。由“铅筒被完全浸没且没有液体溢出水池外”一句可得,若圆锥放入水池后液面高......
  • 「ULSG-1」2048 题解
    题目传送门题目解析玩一次就明白了。传送门解题思路合并从下往上,从左往右,对于每一个非零的数,向上第一个非零数,若与之相等,则此数与找到的数相加,同时分数加上合并后的数,而找到的数清零。若第一个非零数与它不相等,直接停止寻找过程,意为无法合并,等待下落。下落依旧从下往上,从......
  • 「ULSG-1」数字生命 题解
    题目传送门题目描述给定一段长度为\(n\)的序列,找出其中长度为\(m\)的一段子序列,且其中各数字出现次数与给定模板中相对应的次数不相同的数字等于\(k\)。题目解法容易联想到一个用于求固定长度区间最大值的\(O(n)\)算法——「滑动窗口」,此题可借鉴此算法。我们以此题的......
  • 「SiR-1」Checkmate 题解
    题外话:本体题目出自番剧《NOGAMENOLIFE》且题目背景中来吧,游戏开始了。是第一季中男主“空”的口头禅。(强烈推荐观看《NOGAMENOLIFEZERO》)回归正题awaP9355「SiR-1」Checkmate题解题目传送门博客宣传题目解读:在\(n\)行\(m\)列的棋盘中放置多枚棋子,求出其上......
  • 【BZOJ 3156】防御准备 题解
    原题令\(S_{i}=\sum_{j=1}^{i}j\),\(f_{i}\)为处理到第\(i\)个位置放置守卫塔的最小花费。观察题意,容易得到在\((1<=j<=i-1)\)时,有\(f_{i}=min\left\{f_{j}+\sum_{k=j+1}^{i-1}(i-k)+a_{i}\right\}\)①\(f_{i}=min\left\{f_{j}+\sum_{k=j+1}^{i-1}(i-k)\ri......
  • Linux中-bash: /dev/null: Permission denied问题解决
    云上架构2021年08月06日09:19 ·  阅读682​今天在Centos7上运行如下命令 shell复制代码######添加hdfs用户#####useraddhdfs######切换至hdfs用户#####su-hdfs报如下错误 javascript复制代码-bash:/dev/null:Permissiondenied-bash......
  • [ABC114D] 756 题解
    题目链接题意给定一个数\(n\),求\(n!\)的因数中,刚好有\(75\)个因数的数的个数。分析首先有这样一个性质,对于一个数\(a\),我们将其分解质因数,即\[a=\prod_{i=1}^{n}p_i^{k_i}\]那么,\(a\)的因数个数就是\[sum=\prod_{i=1}^{n}(k_i+1)\]简单证明一下,对于第......
  • Alien 的排列题解
    Description求出有多少\(2\simn+1\)的排列\(\{P_{n}\}\),使得对于所有\(1\leqi\leqn\)有\(i|P_{i}\)。对于\(30\%\)的数据\(n\leq10\)。对于\(90\%\)的数据\(n\leq3000\)。对于\(100\%\)的数据\(n\leq10^9\)。Solution如果把\(n+1\)固定在第\(1\)个......
  • 问题解决sql文件上传和蚁剑连接
    1.无法连接上自己的ip:发现问题是上传的木马不在127.0.0.1的文件下时,会导致解析不到木马,要将木马上传到127.0.0.1的文件下连接2.解决sql上传一句话木马问题要先在mysql的配置文件my.ini中添加导入导出数据库的地址:secure_file_priv=D:\phpstudy_pro\WWW然后重启数据库,可以进行sq......