zoukankan      html  css  js  c++  java
  • 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行,每行分别代表墨墨会做的一件事情,格式见题干部分。

    Output

    对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

    Sample Input

    6 5
    1 2 3 4 5 5
    Q 1 4
    Q 2 6
    R 1 2
    Q 1 4
    Q 2 6

    Sample Output

    4
    4
    3
    4

    HINT

    对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。

    ————————————————————————————————————————————————————————————————————————————————

    1、莫队一般情况下是进行数据修改的。如果需要修改时,则在问题的二元组(l,r)中加入第三项pre,构成三元组(l,r,pre)。其中pre表示已经修改过几次。并在排序中加入第三关键字pre。

    2、记录每一次更改,并记录每次更改前后的数据。当由一种询问变到另一种询问时,只要先将pre通过记录的更改变成下一次询问的pre,然后再按照一般莫队算法依次修改 l 和 r,得到最终结果 。

    3、注意:

      a、每次pre的修改,如果修改点在上次查询的范围内,则应当把把对应的ans进行修改。 

      b、每次修改都会对记录数组时行改变。但是查询的状态需要对应状态pre。

        难懂!也就是在查询初始状态时(l=2,r=1)它对应还没有修改过的笔的状态;不能用改了某些笔的姿态来进行查询。

    ————————————————————————————————————————————————————————————————————————————————

      1 #include<bits/stdc++.h>
      2  
      3 using namespace std;
      4 const int maxn=1e4+7;
      5 int n,m,siz;
      6 int cl[maxn],clf[maxn];
      7 int clh[1000007];
      8 char s[2];
      9 struct que
     10 {
     11     int l,r,id,belong,chgd;
     12 }q[maxn];
     13 struct chang
     14 {
     15     int ps,pre,nex,id;
     16 }ch[maxn];
     17 int l,r,c,ans,da[maxn];
     18  
     19 void readint(int &x)
     20 {
     21     char c=getchar();
     22     int f=1;
     23     for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-f;
     24     x=0;
     25     for(;c<='9' && c>='0';c=getchar())x=(x<<1)+(x<<3)+c-'0';
     26     x=x*f;
     27 }
     28 bool cmp(que a,que b)
     29 {
     30     if(a.belong<b.belong)return 1;
     31     if(a.belong==b.belong &&a.r<b.r)return 1;
     32     if(a.belong==b.belong &&a.r==b.r &&a.chgd<b.chgd)return 1;
     33     return 0;
     34 }
     35 void del(int ps)
     36 {
     37     ps=clf[ps];
     38     clh[ps]--;
     39     if(clh[ps]==0)ans--;
     40 }
     41 void add(int ps)
     42 {
     43     ps=clf[ps];
     44     clh[ps]++;
     45     if(clh[ps]==1)ans++;
     46 }
     47 int main()
     48 {
     49     readint(n);readint(m);
     50     for(int i=1;i<=n;i++)
     51     {
     52         readint(cl[i]);clf[i]=cl[i];
     53     }
     54     int bs=sqrt(n+0.5);
     55     int cjs=0,qjs=0;
     56     for(int a,b,i=0;i<m;i++)
     57     {
     58         scanf("%s",s);readint(a);readint(b);
     59         if(s[0]=='Q')
     60         {
     61             q[qjs].l=a;q[qjs].r=b;
     62             q[qjs].id=qjs;q[qjs].belong=(a-1)/bs;
     63             q[qjs].chgd=cjs;
     64             qjs++;
     65         }
     66         else
     67         {
     68             ch[cjs].id=cjs;
     69             ch[cjs].ps=a;
     70             ch[cjs].nex=b;
     71             ch[cjs].pre=cl[a];
     72             cl[a]=b;
     73             cjs++;
     74         }
     75     }
     76     sort(q,q+qjs,cmp);
     77     l=2;r=1;ans=0;c=0;
     78     for(int i=0;i<qjs;i++)
     79     {
     80         while(c<q[i].chgd)
     81         {
     82             if(ch[c].ps>=l && ch[c].ps<=r)
     83             {
     84                 clh[ch[c].pre]--;
     85                 if(clh[ch[c].pre]==0)ans--;
     86                 clh[ch[c].nex]++;
     87                 if(clh[ch[c].nex]==1)ans++;
     88             }
     89             clf[ch[c].ps]=ch[c].nex;
     90             c++;
     91         }
     92         while(c>q[i].chgd)
     93         {
     94             c--;
     95             if(ch[c].ps>=l &&ch[c].ps<=r)
     96             {
     97                 clh[ch[c].pre]++;
     98                 if(clh[ch[c].pre]==1)ans++;
     99                 clh[ch[c].nex]--;
    100                 if(clh[ch[c].nex]==0)ans--;
    101             }
    102             clf[ch[c].ps]=ch[c].pre;
    103         }
    104         while(l<q[i].l)
    105         {
    106             del(l);l++;
    107         }
    108         while(l>q[i].l)
    109         {
    110             l--;add(l);
    111         }
    112         while(r<q[i].r)
    113         {
    114             r++;add(r);
    115         }
    116         while(r>q[i].r)
    117         {
    118             del(r);r--;
    119         }
    120         da[q[i].id]=ans;
    121     }
    122     for(int i=0;i<qjs;i++)printf("%d
    ",da[i]);
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    .NETframework的EF框架学习报错之datetime 数据类型
    String...的用法
    存储过程从入门到熟练(c#篇)
    售前如何做好产品演示
    华为演讲培训售前人员重点学习
    report services 报表开发和部署,集成到解决方案中 全解析
    在Asp.net用C#建立动态Excel(外文翻译)
    NET(C#)连接各类数据库集锦
    在SourceForge.net上如何使用TortoiseCVS
    用C#实现在线升级
  • 原文地址:https://www.cnblogs.com/gryzy/p/6902688.html
Copyright © 2011-2022 走看看