暂无链接
枚举
【题目描述】
有一列整数,共n个。每次可以对这些整数有两种操作:
(1)第i个到第j个整数分别加上数p;
(2)询问这些数中比t小的数的个数。
【输入】
第一行有两个数,n和m(1≤n≤100000,m≤10000),表示数的个数和操作数。
第二行n个整数,表示每个数的初始值。
以后m行,每行开始一个数q。若q为1,则后面跟三个数:i和j(i≤j)表示两个下标,p(-1000≤p≤1000)表示修改的数;若q为2,则为询问操作,后面跟一个数t。
【输出】
对每个询问操作输出数列中比t小的数的个数。
【输入样例】
5 3
1 2 3 4 5
2 0
1 1 5 -10
2 0
【输出样例】
0
5
【提示】
有30%的数据,n和m均不超过1000。
题解
博主用复杂度不对的暴力分块艹过去了。。。
每个块维护最大值最小值和区间加标记,每次修改直接打标记,两端的部分块暴力修改。查询操作直接爆搜所有的块,如果最小值大于查询值跳过,最大值小于查询值直接加上快的大小,如果上述情况都不满足,直接块内爆搜。。。
虽然复杂度完全不对,但就是A了呀。
代码
#include<bits/stdc++.h>
using namespace std;
const int M=1e5+5;
struct sd{
int maxn,minn,le,ri,add;
sd()
{
maxn=-INT_MAX;
minn=INT_MAX;
}
};
sd blo[M];
int n,m,x[M],team[M],sz,tot,r,f;
char c;
int read()
{
r=0,f=1;
c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c))r=(r<<1)+(r<<3)+c-'0',c=getchar();
return r*f;
}
void in()
{
n=read();m=read();
for(int i=1;i<=n;++i)
x[i]=read();
}
void div()
{
sz=sqrt(n);tot=(n-1)/sz+1;
for(int i=1;i<=tot;++i)
{
blo[i].le=(i-1)*sz+1;
blo[i].ri=i*sz;
for(int j=blo[i].le;j<=blo[i].ri;++j)
team[j]=i;
}
for(int i=1;i<=n;++i)
{
blo[team[i]].maxn=max(x[i],blo[team[i]].maxn);
blo[team[i]].minn=min(x[i],blo[team[i]].minn);
}
blo[tot].ri=n;
}
void add(int le,int ri,int ad)
{
int t1,t2,lb,rb;
t1=team[le];
rb=blo[t1].ri;
t2=team[ri];
lb=blo[t2].le;
if(t1==t2)
{
for(int i=le;i<=ri;++i)
{
x[i]+=ad;
blo[t1].maxn=max(blo[t1].maxn,x[i]);
blo[t1].minn=min(blo[t1].minn,x[i]);
}
return;
}
for(int i=le;i<=rb;++i)
{
x[i]+=ad;
blo[t1].maxn=max(blo[t1].maxn,x[i]);
blo[t1].minn=min(blo[t1].minn,x[i]);
}
for(int i=lb;i<=ri;++i)
{
x[i]+=ad;
blo[t2].maxn=max(blo[t2].maxn,x[i]);
blo[t2].minn=min(blo[t2].minn,x[i]);
}
if(t1==t2-1)return;
t1++;t2--;
for(int i=t1;i<=t2;++i)
blo[i].add+=ad;
}
void que(int h)
{
int ans=0;
for(int i=1;i<=tot;++i)
{
if(blo[i].minn+blo[i].add>h)continue;
if(blo[i].maxn+blo[i].add<h)
{
ans+=blo[i].ri-blo[i].le+1;
continue;
}
for(int j=blo[i].le;j<=blo[i].ri;++j)
if(x[j]+blo[i].add<h)ans++;
}
printf("%d\n",ans);
}
void ac()
{
div();
int a,b,c,d;
for(int i=1;i<=m;++i)
{
a=read();b=read();
if(a==2)que(b);
else
{
c=read();d=read();
add(b,c,d);
}
}
}
int main()
{
in();ac();
return 0;
}