题目链接
看这篇学习
给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,单点查值。
代码:
#include
#include
#define min(a,b) (a
给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,询问区间内小于某个值 x^2 的元素个数。
代码:
#include
#include
#include
#include
using namespace std;
int n, blo, bl[50005], v[50005], tag[305];
vector fuck[305];
void reset(int k)
{
fuck[k].clear();
for(int i = min(k*blo,n); i > (k-1)*blo; --i) fuck[k].push_back(v[i]);
sort(fuck[k].begin(), fuck[k].end());
}
void add(int l, int r, int c)
{
for(int i = min(bl[l]*blo, r); i >= l; --i) v[i] += c;
reset(bl[l]);
if(bl[l] != bl[r])
{
for(int i = (bl[r]-1)*blo+1; i <= r; ++i)
v[i] += c;
reset(bl[r]);
}
for(int i = bl[l]+1; i < bl[r]; ++i) tag[i] += c;
}
int query(int l, int r, int c)
{
int ans = 0;
for(int i = min(bl[l]*blo, r); i >= l; --i) if(v[i] + tag[bl[l]] < c) ++ans;
if(bl[l] != bl[r])
{
for(int i = (bl[r]-1)*blo+1; i <= r; ++i) if(v[i] + tag[bl[r]] < c) ++ans;
}
for(int i = bl[l]+1; i < bl[r]; ++i)
{
ans += lower_bound(fuck[i].begin(),fuck[i].end(),c-tag[i]) - fuck[i].begin();
}
return ans;
}
int main()
{
scanf("%d",&n);
blo = sqrt(n);
for(int i = 1; i <= n; ++i)
{
scanf("%d",&v[i]);
bl[i] = (i-1)/blo+1;
fuck[bl[i]].push_back(v[i]);
}
for(int i = 1; i <= bl[n]; ++i) sort(fuck[i].begin(), fuck[i].end());
for(int i = 0; i < n; ++i)
{
int opt, l, r, c;
scanf("%d%d%d%d",&opt,&l,&r,&c);
if(opt) printf("%d\n",query(l,r,c*c));
else add(l,r,c);
}
return 0;
}
给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,询问区间内小于某个值 x 的前驱(比其小的最大元素)。
代码:
#include
#include
#include
using namespace std;
#define ll long long
ll n, blo, bl[1000005], v[1000005], tag[4005];
vector fuck[4005];
void reset(ll k)
{
fuck[k].clear();
for(ll i = min(k*blo,n); i > (k-1)*blo; --i) fuck[k].push_back(v[i]);
sort(fuck[k].begin(), fuck[k].end());
}
void add(ll l, ll r, ll c)
{
for(ll i = min(bl[l]*blo, r); i >= l; --i) v[i] += c;
reset(bl[l]);
if(bl[l] != bl[r])
{
for(ll i = (bl[r]-1)*blo+1; i <= r; ++i)
v[i] += c;
reset(bl[r]);
}
for(ll i = bl[l]+1; i < bl[r]; ++i) tag[i] += c;
}
ll query(ll l, ll r, ll c)
{
ll ans = (1ll<<63);
for(ll i = min(bl[l]*blo, r); i >= l; --i) if(v[i] + tag[bl[l]] > ans && v[i] + tag[bl[l]] < c) ans = v[i] + tag[bl[l]];
if(bl[l] != bl[r])
{
for(ll i = (bl[r]-1)*blo+1; i <= r; ++i) if(v[i] + tag[bl[r]] > ans && v[i] + tag[bl[r]] < c) ans = v[i] + tag[bl[r]];
}
for(ll i = bl[l]+1; i < bl[r]; ++i)
{
ll mmp = lower_bound(fuck[i].begin(),fuck[i].end(),c-tag[i]) - fuck[i].begin()-1;
if(~mmp && fuck[i][mmp]+tag[i] > ans) ans = fuck[i][mmp]+tag[i];
}
if(ans == (1ll<<63)) return -1;
return ans;
}
int main()
{
scanf("%lld",&n);
blo = sqrt(n);
for(ll i = 1; i <= n; ++i)
{
scanf("%lld",&v[i]);
bl[i] = (i-1)/blo+1;
fuck[bl[i]].push_back(v[i]);
}
for(ll i = 1; i <= bl[n]; ++i) sort(fuck[i].begin(), fuck[i].end());
for(ll i = 0; i < n; ++i)
{
ll opt, l, r, c;
scanf("%lld%lld%lld%lld",&opt,&l,&r,&c);
if(opt) printf("%lld\n",query(l,r,c));
else add(l,r,c);
}
return 0;
}