Super Mario
作者:互联网
题目链接:https://vjudge.net/problem/HDU-4417#author=634579757
很经典的分块模版题,出错的都是细节问题,考查学生的码力
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=1e5+10; 7 int a[maxn], temp[maxn]; 8 int t, n, m; 9 int L[maxn], R[maxn], pos[maxn]; 10 void inif(){ 11 memset(L, 0, sizeof(L)); 12 memset(R, 0, sizeof(R)); 13 memset(pos, 0, sizeof(pos)); 14 memset(temp, 0, sizeof(temp)); 15 } 16 void testcode(int num){ 17 printf("aaa[i]:"); 18 for(int i=1; i<=num; i++) 19 for(int j=L[i]; j<=R[i]; j++) 20 printf("%d ",a[j]); 21 printf("\n"); 22 23 printf("tep[i]:"); 24 for(int i=1; i<=num; i++) 25 for(int j=L[i]; j<=R[i]; j++) 26 printf("%d ",temp[j]); 27 printf("\n"); 28 29 printf("pos[i]:"); 30 for(int i=1; i<=num; i++) 31 for(int j=L[i]; j<=R[i]; j++) 32 printf("%d ",pos[j]); 33 printf("\n"); 34 35 printf("iii[i]:"); 36 for(int i=0; i<n; i++)printf("%d ", i);printf("\n"); 37 } 38 void build(){ 39 int t=sqrt(n*1.0); 40 int num=n/t + (n%t != 0); 41 for(int i=1; i<=num; i++){ 42 L[i]=t*(i-1); 43 R[i]=t*i-1; 44 } 45 R[num]=n-1; 46 47 for(int i=1; i<=num; i++){//分段对temp数组排序 48 sort(temp+L[i], temp+R[i]+1);//注意sort函数的区间 49 for(int j=L[i]; j<=R[i]; j++) 50 pos[j]=i;//pos记录每个点属于那一块 51 } 52 //testcode(num);//测试代码 53 } 54 int bs(int l, int r, int h){//二分查找大等于的个数 55 return upper_bound(temp+l, temp+r+1, h)-(temp+l); 56 } 57 int query(int l, int r, int h){ 58 int p=pos[l]; int q=pos[r]; 59 int ret=0; 60 if(p==q){//l,r属于同一块,暴力求解 61 for(int i=l; i<=r; i++) 62 if(a[i]<=h)ret++; 63 } 64 else{ 65 for(int i=l; i<=R[p]; i++)//统计左侧能跳过数 66 if(a[i]<=h) 67 ret++; 68 for(int i=p+1; i<=q-1; i++){//统计中间块二分 69 ret+=bs(L[i], R[i], h); 70 } 71 for(int i=L[q]; i<=r; i++)//统计右侧能跳过数 72 if(a[i]<=h) 73 ret++; 74 } 75 return ret; 76 } 77 int main() 78 { 79 scanf("%d", &t); 80 for(int k=1; k<=t; k++){ 81 inif();//初始化数组 82 scanf("%d%d", &n, &m); 83 for(int i=0; i<n; i++){//注意询问范围是从0~n-1所以存储要从0下标开始 84 scanf("%d",&a[i]); 85 temp[i]=a[i];//存放临时数组用于分块排序 86 } 87 build();//构建分块数组 88 printf("Case %d:\n", k); 89 while(m--){ 90 int l, r, h; 91 scanf("%d%d%d", &l, &r, &h); //注意询问范围是从0~n-1 92 printf("%d\n", query(l, r, h)); 93 } 94 } 95 return 0; 96 }
标签:int,memset,pos,Mario,maxn,sizeof,include,Super 来源: https://www.cnblogs.com/tflsnoi/p/16183193.html