P1903 [国家集训队]数颜色 / 维护队列(莫队区间询问+单点修改)

题目链接:https://www.luogu.org/problemnew/show/P1903

题目大意:中文题目

具体思路:莫队单点修改+区间询问模板题,在原来的区间询问的基础上,我们要记录当前这次操作之前单点修改的操作都有哪些,如果有多余的操作,就先消除这些操作:如果操作数还不够,就在加上这些操作就可以了,这个题会卡常数,注意block的赋值。

block的赋值 = ceil(exp((log(n)+log(num1))/3));这里的num1指的是操作数,n代表点的个数。

然后我们可以对比一下我写的这篇文章,

P1494 [国家集训队]小Z的袜子(莫队)

,在每一次指针的移动的时候,这个题需要把先前的影响给去掉,又因为每一次值的个数需要平方,所以需要先把原来的影响给去掉再去加上新的影响。而这个题我们是只需要判断当前的点是1还是0就可以了。

 

AC代码:

  1 #include<iostream>
  2 #include<cmath>
  3 #include<stdio.h>
  4 #include<algorithm>
  5 #include<string>
  6 #include<cstring>
  7 using namespace std;
  8 # define ll long long
  9 const int maxn = 2e6+100;
 10 int a[maxn],block;
 11 struct node1
 12 {
 13     int l,r,pos,id,num;
 14     bool friend operator < (node1 t1,node1 t2)
 15     {
 16         if(t1.l/block!=t2.l/block)return t1.l/block<t2.l/block;
 17         if(t1.r/block!=t2.r/block)return t1.r/block<t2.r/block;
 18         return t1.num<t2.num;
 19     }
 20 } q1[maxn];
 21 struct node2
 22 {
 23     int pos,val;
 24 } q2[maxn];
 25 int tot,vis[maxn],ans[maxn];
 26 void update(int id,int pos)
 27 {
 28     if(q2[pos].pos>=q1[id].l&&q2[pos].pos<=q1[id].r)
 29     {
 30     if(--vis[a[q2[pos].pos]]==0)
 31         tot--;
 32     if(++vis[q2[pos].val]==1)
 33         tot++;
 34     }
 35     swap(a[q2[pos].pos],q2[pos].val);
 36 }
 37 inline int read()
 38 {
 39     char c=getchar();int x=0,f=1;
 40     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
 41     while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
 42     return x*f;
 43 }
 44 void solve(int num1)
 45 {
 46     int num=0,l=1,r=0;
 47     tot=0;
 48     for(int i=1; i<=num1; i++)
 49     {
 50         while(l<q1[i].l)if(--vis[a[l++]]==0)tot--;
 51         while(l>q1[i].l)if(++vis[a[--l]]==1)tot++;
 52         while(r<q1[i].r)if(++vis[a[++r]]==1)tot++;
 53         while(r>q1[i].r)if(--vis[a[r--]]==0)tot--;
 54         while(num<q1[i].num){
 55             num++;
 56             update(i,num);
 57         }
 58         while(num>q1[i].num)
 59         {
 60             update(i,num);
 61             num--;
 62         }
 63         ans[q1[i].id]=tot;
 64     }
 65     return ;
 66 }
 67 int main()
 68 {
 69    // cout<<pow(50000,5.0/3.0)<<endl;
 70    // memset(vis,0,sizeof(vis));
 71    // freopen("hqx.in","r",stdin);
 72     int n,m;
 73     n=read();
 74     m=read();
 75     //scanf("%d %d",&n,&m);
 76     for(int i=1; i<=n; i++)
 77     {
 78         a[i]=read();
 79     }
 80     char str[10];
 81     int st,ed;
 82     int num1=0,num2=0;
 83     while(m--)
 84     {
 85         scanf("%s",str);
 86         st=read();
 87         ed=read();
 88         if(str[0]=='Q')
 89         {
 90             q1[++num1].l=st;
 91             q1[num1].r=ed;
 92             q1[num1].num=num2;
 93             q1[num1].id=num1;
 94         }
 95         else if(str[0]=='R')
 96         {
 97             q2[++num2].pos=st;
 98             q2[num2].val=ed;
 99         }
100     }
101     block=ceil(exp((log(n)+log(num1))/3));
102     sort(q1+1,q1+num1+1);
103     solve(num1);
104     for(int i=1; i<=num1; i++)
105     {
106         printf("%d\n",ans[i]);
107     }
108 //    for(int i=1;i<=5;i++){
109 //    cout<<i<<" "<<vis[i]<<endl;
110 //    }
111     return 0;
112 }

 

posted @ 2019-03-09 11:33  Let_Life_Stop  阅读(325)  评论(0编辑  收藏  举报