2019南昌icpc网络赛 I题 分块套BIT

Posted nervendnig

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019南昌icpc网络赛 I题 分块套BIT相关的知识,希望对你有一定的参考价值。

https://nanti.jisuanke.com/t/41356

技术图片

对于带修的二维数点,可以bit套主席树,也可CDQ三维偏序

但是最后我选择分块套BIT暴力...

复杂度为$m(blocksize*logn+blocknum)$

显然,如果按照$\\sqrtn$分块,并不是最优的

我们可以适当的增加块的大小,减少块的数量,让$blocksize*logn=blocknum$

在这个题中,大概就是$\\sqrt1e6$到$\\sqrt2e6$之间吧

技术图片

#include<bits/stdc++.h>
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
using namespace std;
const int maxn=2e5+10,maxm=6e2+10;
int n,m;
namespace fastio
inline bool isdigit(char c)return c>=48&&c<=57;
const int maxsz=1e7;
class fast_iostreampublic:
  char ch=get_char();
  inline char get_char()
    static char buffer[maxsz],*a=buffer,*b=buffer;
    return b==a&&(b=(a=buffer)+fread(buffer,1,maxsz, stdin),b==a)?EOF:*a++;
  
  void operator>>(int& tmp)
    tmp=0;
    while(!isdigit(ch)&&ch!=EOF)ch=get_char();;
    if(ch==EOF)return ;
    dotmp=ch-48+(tmp<<1)+(tmp<<3);while(isdigit(ch=get_char()));
  
;
int top;char stk[8];
void put(int &tmp)
  if (!tmp)putchar(‘0‘);return;
  top=0;
  while(tmp)stk[++top]=tmp%10+‘0‘,tmp/=10;
  while(top)putchar(stk[top--]);

fastio::fast_iostream io;
class bitpublic:
  int node[maxn];
  inline int lb(int x) return x&(-x);
  inline void update(int pos,int val)
    for(;pos<=n;pos+=lb(pos)) node[pos]+=val;
  
  inline int ask(int pos)
    int sum=0;
    for(;pos>0;pos-=lb(pos)) sum+=node[pos];
    return sum;
  
  inline int query(int l,int r)
    return ask(r)-ask(l-1);
  
;
int aa[maxn],bb[maxn];
class sqblockpublic:
  struct block
    int l,r;bit tree;
    void update(int pos,int val) tree.update(pos,val);
    int query(int l,int r) return tree.query(l,r);
  node[maxm];
  int id[maxn],sz,cnt;
  void init(int n)
    sz=sqrt(2e6);
    rep(i,1,n) id[i]=(i-1)/sz+1;cnt=id[n];
    rep(i,1,cnt) node[i].l=(i-1)*sz+1;
    rep(i,1,cnt-1) node[i].r=i*sz;
    node[cnt].r=n;
    rep(i,1,n)if(aa[i]!=aa[i-1]) node[id[i]].update(aa[i],1);
  
  void update(int x,int y)
    if(x>1&&aa[x]!=aa[x-1]) node[id[x]].update(aa[x],-1);
    if(x<n&&aa[x+1]!=aa[x]) node[id[x+1]].update(aa[x+1],-1);
    aa[x]=y;
    if(x>1&&aa[x]!=aa[x-1]) node[id[x]].update(aa[x],1);
    if(x<n&&aa[x+1]!=aa[x]) node[id[x+1]].update(aa[x+1],1);
  
  int query(int l,int r,int x,int y)
    int posl=id[l],posr=id[r],ans=0;
    if(posl==posr) 
      rep(i,l,r) ans+=(aa[i]!=aa[i-1]&&aa[i]>=x&&aa[i]<=y);
      return ans;
    
    rep(i,posl+1,posr-1) ans+=node[i].query(x,y);
    rep(i,l,node[posl].r) ans+=(aa[i]!=aa[i-1]&&aa[i]>=x&&aa[i]<=y);
    rep(i,node[posr].l,r) ans+=(aa[i]!=aa[i-1]&&aa[i]>=x&&aa[i]<=y);
    return ans;
  
square;
int x,y,b,c,d,e,a,ans;
#define cin io
int main() 
  cin>>n;cin>>m;
  rep(i,1,n) cin>>aa[i];
  square.init(n);
  while(m--)
    cin>>a;
    if(a==1)
      cin>>x;cin>>y;
      if(aa[x]!=y) square.update(x,y);
    else 
      cin>>b;cin>>c;cin>>d;cin>>e;
      ans=square.query(b,c,d,e);
      if(aa[b]==aa[b-1]&&aa[b]>=d&&aa[b]<=e) ans++;
      fastio::put(ans);putchar(‘\\n‘);
    
  

 

以上是关于2019南昌icpc网络赛 I题 分块套BIT的主要内容,如果未能解决你的问题,请参考以下文章

ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval

2019 ICPC 南昌网络赛

2019ICPC南昌网络赛总结

2019南昌网络赛-I. Yukino With Subinterval 线段树套树状数组

2019 ICPC 南昌网络赛 - Max answer (区间和,区间最值)

2019 ICPC 南昌网络赛 - Subsequence (子串判断,预处理,超时)