zoukankan      html  css  js  c++  java
  • 算法复习——带修改莫队(bzoj2453)

    题目:

    Description

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

    Input

    输入文件第一行包含两个整数N和M。
    第二行N个整数,表示初始队列中弹珠的颜色。
    接下来M行,每行的形式为“Q L R”或“R x c”,“Q L R”表示A想知道从队列第L个弹珠到第R个弹珠中,一共有多少不同颜色的弹珠,“R x c”表示A把x位置上的弹珠换成了c颜色。

    Output

    对于每个Q操作,输出一行表示询问结果。

    Sample Input


    2 3
    1 2
    Q 1 2
    R 1 2
    Q 1 2

    Sample Output

    2
    1

    HINT

    对于100%的数据,有1 ≤ N ≤ 10000, 1 ≤ M ≤ 10000,小朋友A不会修改超过1000次,所有颜色均用1到10^6的整数表示。

    Source

    题解:

      带修改莫队就是莫队原有排序基础上加个第三关键字:时间,注意排序的顺序都是以所在块为顺序另外利用判断是否在指针内的数组visit[i]结合一个巧妙的change和update操作,另外注意分块的大小为n的2/3次方.

    具体见http://blog.csdn.net/doyouseeman/article/details/51869932

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=1e4+5;
    const int M=1e6+5;
    inline int R()
    {
      char c;int f=0;
      for(c=getchar();c<'0'||c>'9';c=getchar());
      for(;c<='9'&&c>='0';c=getchar())
        f=(f<<3)+(f<<1)+c-'0';
      return f;
    }
    struct node
    {
      int l,r,x,id;
    }ask[N];
    struct node2
    {
      int po,va,pre;
    }modi[N];
    int s,n,m,cnt[M],last[N],tots,tota,totm,num[N],id[N],head,tail,now,ans,anss[N];
    bool visit[N];
    inline bool cmp(node a,node b)
    {
      return (id[a.l]<id[b.l])||(id[a.l]==id[b.l]&&id[a.r]<id[b.r])||(id[a.l]==id[b.l]&&id[a.r]==id[b.r]&&a.x<b.x);
    }
    inline void update(int pos)
    {
      if(visit[pos])
      {
        cnt[num[pos]]--;
        if(!cnt[num[pos]])  ans--;
      }
      else
      {
        cnt[num[pos]]++;
        if(cnt[num[pos]]==1)  ans++;
      }
      visit[pos]^=1;
    }
    inline void change(int pos,int val)
    {
      if(visit[pos])
      {
        update(pos);
        num[pos]=val;
        update(pos);
      }
      else
        num[pos]=val;
    }
    int main()
    {
      n=R(),m=R();s=pow(n,2.0/3.0);
      for(int i=1;i<=n;i++)
        num[i]=R(),last[i]=num[i];
      for(int i=1;i<=n;i++)
        id[i]=i/s+1;int a,b;char t[5];
      for(int i=1;i<=m;i++)
      {
        scanf("%s",t);
        if(t[0]=='Q')
          ask[++tota].l=R(),ask[tota].r=R(),ask[tota].x=totm,ask[tota].id=tota;
        else
          modi[++totm].po=R(),modi[totm].va=R(),modi[totm].pre=last[modi[totm].po],last[modi[totm].po]=modi[totm].va;
      } 
      sort(ask+1,ask+tota+1,cmp);head=1;
      for(int i=1;i<=tota;i++)
      {
        if(ask[i].x>now)  for(int j=now+1;j<=ask[i].x;j++)  change(modi[j].po,modi[j].va);
        else for(int j=now;j>=ask[i].x+1;j--)  change(modi[j].po,modi[j].pre);
        if(head<ask[i].l)  for(int j=head;j<=ask[i].l-1;j++)  update(j);
        else for(int j=ask[i].l;j<=head-1;j++)  update(j);
        if(tail>ask[i].r)  for(int j=ask[i].r+1;j<=tail;j++)  update(j);
        else for(int j=tail+1;j<=ask[i].r;j++)  update(j);
        head=ask[i].l,tail=ask[i].r,now=ask[i].x,anss[ask[i].id]=ans;
      }
      for(int i=1;i<=tota;i++)
        printf("%d
    ",anss[i]);
      return 0;
    }
     
     
  • 相关阅读:
    数据可视化之DAX篇(二十)Think in DAX 之报表自动化实践
    数据可视化之DAX篇(十九)值得你深入了解的函数:SUMMARIZE
    数据可视化之DAX篇(十八)收藏 | DAX代码格式指南
    数据可视化之DAX篇(十七)Power BI表格总计行错误的终极解决方案
    atomic_compare_exchange_weak_explicit (Atomic operations) – C 中文开发手册
    Spring Boot的How-to指南:嵌入式Web服务器
    C# 文本文件的读写
    CSS outline 属性
    operator (Numeric & Mathematical) – Python 中文开发手册
    HTML DOM Style animationDirection 属性
  • 原文地址:https://www.cnblogs.com/AseanA/p/7512138.html
Copyright © 2011-2022 走看看