思路:分块+二分
这道题也调试了很长时间,还有莫名RE,可是明明数组已经开够了啊,还是要再开大一点。
记录下代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int maxn = 100010; 7 const int maxm = 330; 8 9 struct u { 10 int v,i; 11 bool operator < (const u &rhs) const { 12 return v < rhs.v; 13 } 14 }B[maxn+maxm]; 15 16 int n, N, S; 17 int A[maxn], ID[maxn], addv[maxm], ind[maxn]; 18 19 void update(int x,int k) { 20 while(B[x].v > B[x+1].v && x != ID[k]*S) { 21 ind[B[x].i] = x+1; 22 ind[B[x+1].i] = x; 23 swap(B[x],B[x+1]); 24 x++; 25 } 26 27 while(B[x].v < B[x-1].v && x != (ID[k]-1)*S+1) { 28 ind[B[x].i] = x-1; 29 ind[B[x-1].i] = x; 30 swap(B[x],B[x-1]); 31 x--; 32 } 33 } 34 35 void add(int x,int y,int c) { 36 if(ID[x] + 1 >= ID[y]) { 37 for(int i = x;i <= y;i++) { 38 A[i] += c; 39 B[ind[i]].v -= c; 40 update(ind[i],i); 41 } 42 return; 43 } 44 45 int l = ID[x]+1, r = ID[y]-1; 46 for(int i = l;i <= r;i++) addv[i] += c; 47 48 for(int i = x;i <= y;) { 49 A[i] += c; 50 B[ind[i]].v -= c; 51 update(ind[i],i); 52 if(i == (l-1)*S) i = r*S + 1; 53 else i++; 54 } 55 return; 56 } 57 58 int query(int x,int y,int c) { 59 int ret = -(1<<30); 60 if(ID[x] + 1 >= ID[y]) { 61 for(int i = x;i <= y;i++) { 62 if(A[i] + addv[ID[i]] >= c) continue; 63 ret = max(ret, A[i] + addv[ID[i]]); 64 } 65 if(ret == -(1<<30)) return -1; 66 else return ret; 67 } 68 69 int l = ID[x] + 1, r = ID[y] - 1; 70 for(int i = l;i <= r;i++) { 71 int ed = i*S; 72 int be = (i-1)*S + 1; 73 if(-B[ed].v + addv[i] < c) { 74 u tp = *upper_bound(B+be,B+be+S,(u){-(c-addv[i]),0}); 75 ret = max(ret, -tp.v + addv[i]); 76 } 77 } 78 79 for(int i = x;i <= y;) { 80 if(A[i] + addv[ID[i]] >= c) { 81 if(i == (l-1)*S) i = r*S + 1; 82 else i++; 83 continue; 84 } 85 ret = max(ret, A[i] + addv[ID[i]]); 86 if(i == (l-1)*S) i = r*S + 1; 87 else i++; 88 } 89 if(ret == -(1<<30)) return -1; 90 else return ret; 91 } 92 93 int main() { 94 scanf("%d",&n); 95 96 S = sqrt(n); 97 N = (n-1)/S + 1; 98 for(int i = 1;i <= n;i++) { 99 scanf("%d",&A[i]); 100 B[i].v = -A[i]; 101 B[i].i = i; 102 ID[i] = (i-1)/S + 1; 103 } 104 105 for(int i = 1;i <= N;i++) { 106 int be = (i-1)*S + 1; 107 cout<<be<<endl; 108 sort(B+be,B+be+S); 109 } 110 111 for(int i = 1;i <= n;i++) { 112 ind[B[i].i] = i; 113 } 114 115 int opt,l,r,c; 116 117 for(int i = 1;i <= n;i++) { 118 scanf("%d %d %d %d",&opt,&l,&r,&c); 119 if(!opt) add(l,r,c); 120 else printf("%d ", query(l,r,c)); 121 } 122 return 0; 123 }