BZOJ3343 教主的魔法 二分法+分块
生活随笔
收集整理的這篇文章主要介紹了
BZOJ3343 教主的魔法 二分法+分块
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:給定一個數(shù)列,維護:1、[L,R]之間所有的數(shù)+=W? 2、求[L,R]中大于等于C的數(shù)的數(shù)量
題解:更新用add標(biāo)記,頭尾倆塊暴力重構(gòu);查詢將每個塊排序然后二分找。
#include <cmath> #include <ctime> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std;const int MAXS=1000+2; struct BLOCK{int a[MAXS],b[MAXS],add; }block[MAXS]; int N,M,S; char s;void Update(int l,int r,int x){if((l-1)%S){int p=(l-1)/S+1;for(int i=l-S*(p-1);i<=S && i<=r-(p-1)*S;i++) block[p].a[i]+=x;for(int i=1;i<=S;i++) block[p].b[i]=block[p].a[i];sort(block[p].b+1,block[p].b+S+1);l=p*S+1;}while(l+S-1<=r) block[l/S+1].add+=x,l+=S;if(r%S){int p=l/S+1;r-=S*(p-1);for(int i=1;i<=r;i++) block[p].a[i]+=x;for(int i=1;i<=S;i++) block[p].b[i]=block[p].a[i];sort(block[p].b+1,block[p].b+S+1);} }int Find(int p,int l,int r,int c){c-=block[p].add;int m=(l+r)>>1;while(l<=r){if(block[p].b[m]<c) l=m+1;else r=m-1;m=(l+r)>>1;}return S-l+1; }int Query(int l,int r,int c){int ret=0;if((l-1)%S){int p=(l-1)/S+1;for(int i=l-S*(p-1);i<=r-S*(p-1) && i<=S;i++)if(block[p].a[i]>=c-block[p].add) ret++;l=p*S+1;}while(l+S-1<=r) ret+=Find(l/S+1,1,S,c),l+=S;if(r%S){int p=l/S+1;for(int i=1;i<=r-S*(p-1);i++)if(block[p].a[i]>=c-block[p].add) ret++;}return ret; }int main(){memset(block,0X7F,sizeof(block));block[1].add=0;cin >> N >> M,S=(int)sqrt(N);for(int i=1,j=1,k=1;i<=N;i++,j++){cin >> block[k].a[j],block[k].b[j]=block[k].a[j];if(j==S || i==N){sort(block[k].b+1,block[k].b+j+1);k++,j=0,block[k].add=0;}}N=(N%S?N/S+1:N/S);for(int i=1,l,r,x;i<=M;i++){cin >> s;cin >> l >> r >> x;if(s=='M') Update(l,r,x);if(s=='A') cout << Query(l,r,x) << endl;}return 0; } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/WDZRMPCBIT/p/6464169.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ3343 教主的魔法 二分法+分块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [deviceone开发]-心形点赞动画
- 下一篇: torch学习笔记--tensor介绍2