60分求助(小数据也WA了)

P2801 教主的魔法

lindongli2004 @ 2018-11-17 16:13:23

#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int N=2002017;
vector <int> ve[2050];
int n,m,as[N],blo,bl[N],siz[N],tag[N];
void reset(int x)
{
    ve[x].clear();
    for(int i=(x-1)*blo+1;i<=min(n,x*blo);i++)
    {
      as[i]+=tag[x];
      ve[x].push_back(as[i]);
    }
    sort(ve[x].begin(),ve[x].end());
    tag[x]=0;
}
void change(int a,int b,int c)
{
    if(tag[bl[a]])reset(bl[a]);
    for(int i=a;i<=min(b,bl[a]*blo);i++)
      as[i]+=c;
    reset(bl[a]);
    if(bl[b]!=bl[a])
    {
      if(tag[bl[b]])reset(bl[b]);
      for(int i=(bl[b]-1)*blo+1;i<=b;i++)
        as[i]+=c;
      reset(bl[b]);
    }
    for(int i=bl[a]+1;i<=bl[b]-1;i++)
      tag[i]+=c;
}
int find(int x,int c)
{
    int l=0,r=siz[x]-1;
    int now=c-tag[x],ans=siz[x]-1;
    while(l<=r)
    {
      int mid=(l+r)/2;
      if(now>ve[x][mid])l=mid+1;
      else r=mid-1,ans=mid;
    }
    if(ve[x][ans]>=now)return siz[x]-ans;
    else return siz[x]-1-ans;
}
int query(int a,int b,int c)
{
    int res=0;
    if(tag[bl[a]])reset(bl[a]);
    for(int i=a;i<=min(b,bl[a]*blo);i++)
      if(as[i]>=c)++res;
    if(bl[b]!=bl[a])
    {
      if(tag[bl[b]])reset(bl[b]);
      for(int i=(bl[b]-1)*blo+1;i<=b;i++)
        if(as[i]>=c)++res;
    }
    for(int i=bl[a]+1;i<=bl[b]-1;i++)
      res+=find(i,c);
    return res;
}
int main()
{
    cin>>n>>m;blo=sqrt(n);
    for(int i=1;i<=n;i++)cin>>as[i];
    for(int i=1;i<=n;i++)
    {
      bl[i]=(i-1)/blo+1;
      ve[bl[i]].push_back(as[i]);
      ++siz[bl[i]];
    }
    for(int i=1;i<=blo;i++)
      sort(ve[i].begin(),ve[i].end());
    for(int i=1;i<=m;i++)
    {
      char ch;int a,b,c;
      cin>>ch>>a>>b>>c;
      if(ch=='M')change(a,b,c);
      else cout<<query(a,b,c)<<endl;
    }
    return 0;
}

|