• 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
    ", query(l,r,c));
    121     }
    122     return 0;
    123 } 
  • 相关阅读:
    第一次程序改错
    趣拼图——项目演示及代码
    数据流图和数据流程图
    UML图
    UML用例图
    第二次迭代目标的分配
    小组分工
    迭代目标
    我们的项目
    2017-4-18 关于小组APP
  • 原文地址:https://www.cnblogs.com/frankscode/p/9511967.html
Copyright © 2020-2023  润新知