HDU - 4417 Super Mario
放个传送门开溜
题意
给你一串序列,每次询问L~R范围内小于等于H数字的个数
题解
由于今天我们学的分块,所以被逼用分块
关于分块,蒟蒻不再赘述,推荐一篇讲分块的blog
还是运用分块的思想,小于bol(bol为每块的长度)的首尾,暴力求ans
中间排好序用STL中的upper_bound统计小于等于H的
完了
注意
卡常是要卡滴,o2是要开的
注意好像原序列从0开始排,所以如果习惯for(int i=1;i<=n;++i),记得L++,R++
CODE
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<algorithm> #pragma GCC optimize (2) #pragma G++ optimize (2) #define N 100005 #define rint register int using namespace std; int t,n,m,bol,v[N],bel[N]; vector<int> xl[400]; inline int read() { rint x=0,f=1;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void write(int x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } inline int query(int a,int b,int h) { rint ans=0; for(rint i=a;i<=min(bel[a]*bol,b);++i) if(v[i]<=h) ++ans; if(bel[a]!=bel[b]) for(rint i=(bel[b]-1)*bol+1;i<=b;++i) if(v[i]<=h) ++ans; for(rint i=bel[a]+1;i<bel[b];++i) { if(h<*xl[i].begin()) continue; ans+=upper_bound(xl[i].begin(),xl[i].end(),h)-xl[i].begin(); } return ans; } int main() { //freopen("2.out","w",stdout); t=read(); for(rint qwq=1;qwq<=t;++qwq) { rint a,b,h; n=read();m=read();bol=sqrt(n); for(rint i=1;i<=n;++i) v[i]=read(),bel[i]=(i-1)/bol+1,xl[bel[i]].push_back(v[i]); for(rint i=1;i<=bel[n];++i) sort(xl[i].begin(),xl[i].end()); if(qwq!=1) putchar('\n'); putchar('C');putchar('a');putchar('s');putchar('e');putchar(' ');write(qwq);putchar(':'); for(rint i=1;i<=m;++i) { a=read();b=read();h=read();a++;b++; putchar('\n');write(query(a,b,h)); } if(qwq!=t) for(rint i=1;i<=n;++i) xl[i].clear(); if(qwq==t) putchar('\n'); } return 0; }
其他
推荐题目,与本题相似