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

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

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

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

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

显然,如果按照$\sqrt{n}$分块,并不是最优的

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

在这个题中,大概就是$\sqrt{1e6}$到$\sqrt{2e6}$之间吧

#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_iostream{public:
  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 ;
    do{tmp=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 bit{public:
  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 sqblock{public:
  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‘);
    }
  }
}

原文地址:https://www.cnblogs.com/nervendnig/p/11498520.html

时间: 2024-07-30 13:58:49

2019南昌icpc网络赛 I题 分块套BIT的相关文章

hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题

题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给定的学生成绩都异或上一次的答案 先将学生按每一门成绩都排一次序 这里将学生分块成sqrt(n)的块数,然后在当前块中用bitset容器来记录含有学生的状态 这里可以记录状态的前缀和,因为比后面成绩好的,必然比前面的学生的成绩也好 查询的时候只要查到正好比他高的学生属于哪一块,这样只要访问sqrt(n

2019上海icpc网络赛B. Light bulbs(思维+差分)

题目传送门 题意 T组案例,每组案例:n个灯泡(from 0 to n-1),m次操作,每次操作把区间[L,R]内的灯泡翻转(开变关,关变开),问m次操作之后有多少灯泡是亮着的.(时间限制:1000ms  内存限制:8192K) 题解 这道题不仅卡时间,更是卡内存,所以用线段树会爆内存 正解: 该题可以转换为经典的差分问题:每次操作对[L,R]的所有数进行+1操作,求最后有多少个奇数.(设该数组为a[n],每次操作a[L]+1,a[R+1]-1,求前缀和sum[i]=sum[i-1]+a[i]即

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

ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询问子区间中某个值域的数的个数,连续的相同数字只记为一个.(即统计数字段的个数) 2 L R x y 数据范围: 1 ≤ n,m ≤ 2×10^5 1 ≤ a[i] ≤ n 解题思路: 连续重复的数字只记一次.所以考虑将每个数字段除第一个出现外的数字都删去(记为0).在读入操作的时候暴力模拟,同时维护

hihocoder1236(北京网络赛J):scores 分块+bitset

北京网络赛的题- -.当时没思路,听大神们说是分块+bitset,想了一下发现确实可做,就试了一下,T了好多次终于过了 题意: 初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查询的五种能力值,输出有多少个人每种能力值都比查询的小 n和q都是50000,每种能力值最大也为50000 思路: 对于某一个大小的能力值,有哪些人的此项能力值比他小可以用一个50000的bitset表示.这样我们在查询的时候就可以拿到5个对应的bitset,对其进行and就可以得出最终的人数 这样每

hdu4271 Find Black Hand 2012长春网络赛E题 最短编辑距离

hdu4271 Find Black Hand  2012长春网络赛E题  最短编辑距离 Find Black Hand Time Limit : 5000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 19   Accepted Submission(s) : 1 Problem Description I like playing game with my friend

2015北京网络赛A题The Cats&#39; Feeding Spots

题意:给你一百个点,找个以这些点为中心的最小的圆,使得这个圆恰好包含了n个点,而且这个圆的边界上并没有点 解题思路:暴力枚举每个点,求出每个点到其他点的距离,取第n大的点,判断一下. 1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<memory.h> 6 using namespace std; 7 const i

西电校赛网络赛J题 lucas定理计算组合数

西电校赛网络赛J题  lucas定理计算组合数 问题 J: 找规律II 时间限制: 1 Sec  内存限制: 128 MB 提交: 96  解决: 16 [提交][状态][讨论版] 题目描述 现有数阵如下: 1    2  3   4     5    6 1   3   6  10  15 1   4  10   20 1   5   15 1    6 1 求这个数阵的第n行m列是多少(行列标号从1开始) 结果对10007取模 输入 多组数据,每组数据一行,包含两个整数n,m(1<=n<=

HDU 5024 Wang Xifeng&#39;s Little Plot(广州网络赛C题)

HDU 5024 Wang Xifeng's Little Plot 题目链接 思路:先利用记忆化搜索预处理出每个结点对应8个方向最远能走多远,然后枚举拐点记录最大值即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int d[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1,

Ryuji doesn&#39;t want to study 2018徐州icpc网络赛 树状数组

Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]. Unfortunately, the longer he learns, the fewer he gets. That means, if he reads books from ll to rr, he will get a