LOJ 6279 数列分块入门3 分块基础

思路:分块+二分

这道题也调试了很长时间,还有莫名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\n", query(l,r,c));
121     }
122     return 0;
123 } 

 

posted @ 2018-08-21 16:08  Frank的成长之路  阅读(215)  评论(0编辑  收藏  举报