【BZOJ】3343 教主的魔法 分块
来源:互联网 发布:excel如何导入外部数据 编辑:程序博客网 时间:2024/04/30 08:24
题目传送门
分块什么的最好了~(至少简单易懂,代码还比较好写)
这题就当是我学习了分块的flag吧。
其实分块就是把原来n个元素分成sqrt(n)块,每块有sqrt(n)个元素。
对于一段连续的区间修改,我们可以把这个区间分成若干个完整的块和两端剩下的元素。
对于完整的块,我们可以用和线段树一样的思想——延迟标记来记录当前块内所有元素的共同修改量;
对于两端剩下的元素,我们可以暴力修改。(暴力大法好~)
对于询问,我们可以再开一个数组,和之前的数组一样分块,但是要把每个块内的元素排序。
然后我们把询问拆分成若干个完整的块和两端剩下的元素。
对于完整的块,我们可以二分出块内的答案;对于两端剩下的元素,依然是暴力……
综上,这道题就被分块水过去了。(因为询问的次数比较小嘛)
附上AC代码:
#include <cstdio>#include <cctype>#include <cmath>#include <algorithm>#define N 1010using namespace std;int n,m,size,num,a[N*N],l[N],r[N],b[N*N],x,y,w,sy[N*N],lz[N];char c;inline char nc(){static char ch[100010],*p1=ch,*p2=ch;return p1==p2&&(p2=(p1=ch)+fread(ch,1,100010,stdin),p1==p2)?EOF:*p1++;}inline void read(int &a){static char c=nc();int f=1;for (;!isdigit(c);c=nc()) if (c=='-') f=-1;for (a=0;isdigit(c);a=a*10+c-'0',c=nc());a*=f;return;}inline void rebuild(int x){for (int i=l[x]; i<=r[x]; ++i) b[i]=a[i];return sort(b+l[x],b+r[x]+1);}inline void change(int x,int y,int w){if (sy[x]==sy[y]){for (int i=x; i<=y; ++i) a[i]+=w;return rebuild(sy[x]);}for (int i=sy[x]+1; i<=sy[y]-1; ++i) lz[i]+=w;for (int i=x; i<=r[sy[x]]; ++i) a[i]+=w;rebuild(sy[x]);for (int i=l[sy[y]]; i<=y; ++i) a[i]+=w;rebuild(sy[y]);return;}inline int find(int x,int y,int w){int l=x,r=y,ans=y+1,mid;while (l<=r){mid=(l+r)>>1;if (b[mid]<w) l=mid+1;else ans=mid,r=mid-1;}return y-ans+1;}inline int query(int x,int y,int w){int ans=0;if (sy[x]==sy[y]){for (int i=x; i<=y; ++i) if (a[i]>=w) ++ans;return ans;}for (int i=sy[x]+1; i<=sy[y]-1; ++i) ans+=find(l[i],r[i],w-lz[i]);for (int i=x; i<=r[sy[x]]; ++i) if (a[i]>=w) ++ans;for (int i=l[sy[y]]; i<=y; ++i) if (a[i]>=w) ++ans;return ans;}int main(void){read(num),read(m),size=sqrt(num),n=(num-1)/size+1; for (int i=1; i<=num; ++i){read(a[i]),b[i]=a[i],sy[i]=(i-1)/size+1;if (i%size==1) l[sy[i]]=i;if (i%size==0) r[sy[i]]=i;}if (!r[n]) r[n]=num;for (int i=1; i<=n; ++i) sort(b+l[i],b+r[i]+1);while (m--){c=nc();while (c!='M'&&c!='A') c=nc();read(x),read(y),read(w);switch (c){case 'M': change(x,y,w); break;case 'A': printf("%d\n",query(x,y,w)); break;}}return 0;}
阅读全文
0 0
- BZOJ 3343 教主的魔法 分块
- BZOJ 3343: 教主的魔法|分块
- bzoj 3343: 教主的魔法 分块+二分
- BZOJ 3343: 教主的魔法 分块算法
- bzoj 3343 教主的魔法 分块
- 【BZOJ】3343 教主的魔法 分块
- BZOJ 3343 教主的魔法 分块
- [BZOJ] 3343 教主的魔法 分块
- [BZOJ]3343: 教主的魔法 分块+二分
- BZOJ 3343: 教主的魔法【分块基础题
- Bzoj 3343: 教主的魔法(分块+二分答案)
- BZOJ 3343 教主的魔法 暴力分块做法
- BZOJ 3343: 教主的魔法 分块大暴力
- 【BZOJ】【P3343】【教主的魔法】【题解】【分块】
- 分块-教主的魔法
- [BZOJ 3343]教主的魔法
- 【bzoj 3343】教主的魔法
- bzoj 3343: 教主的魔法
- Python爬虫Xpath和lxml类库系列之九
- HDU-5367 digger(线段树区间合并)
- c++中new/delete与malloc/free的区别与联系
- 菱形继承
- git--多人合作
- 【BZOJ】3343 教主的魔法 分块
- UVA
- nfs的初探
- android_在线播放器
- Salty Fish
- jQuery Mobileb 入门学习(1)
- POJ2482-Stars in Your Window
- 关于hive中decode函数,默认转码没有GBK中文字符集的问题
- C语言中的时间函数