codoeforces 102920 I 题解

题意:

给你一个长为$n$的数字串,有正数和负数,和$m$个询问。每个询问询问你区间$[L,R]$中权值和小于$U$的子区间中权值和最大是多少。

$n<=2000,m<=200000$

可以发现,n很小,m较大,因此,我们可以先预处理出来所有子区间的和,然后将子区间按照权值和从小到大排序。然后我们对整个串进行分块。

对于每一个块,我们利用树状数组维护以这个块中的某个点为左端点的区间的最大值。对于块中的每个位置,我们利用树状数组维护以他为左端点的区间的最大值。

之后我们将询问也从小到大排列,将所有树状数组的初始值都赋为-inf。之后我们每计算一个询问,就把新的合法的序列放进对应的块的树状数组里以及他左端点的树状数组里。

询问的时候,对于整个块位于区间内的,查询块的树状数组的前缀最大值,否则便利位置,查每个位置树状数组的前缀最大值。

1 #include<iostream>  2 #include<cstdlib>  3 #include<cstdio>  4 #include<cstring>  5 #include<algorithm>  6 #include<queue>  7 #define N 2005  8 #define M 200005  9 #include<cmath> 10 #define lowbit(i) (i&(-i)) 11 using namespace std; 12 int n,m; 13 int A[N]; 14 typedef pair<long long,pair<int,int>> T; 15 long long ans[M]; 16 struct no{ 17     int l,r,bh; 18     long long data; 19 }q[M]; 20 priority_queue<T,vector<T>,greater<T > > q1; 21 int len,bel[N]; 22 int st[N]; 23 long long B[N][N]; 24 long long C[N][N]; 25 bool cmp(const no &a,const no &b) 26 { 27     return a.data<b.data;     28 } 29 void add1(int x,int y,long long data) 30 { 31     for(int i=y;i<=n;i =lowbit(i)) 32     { 33         B[x][i]=max(B[x][i],data); 34     } 35 } 36 void add2(int x,int y,long long data) 37 { 38     for(int i=y;i<=n;i =lowbit(i)) 39     { 40         C[x][i]=max(C[x][i],data); 41     } 42 } 43 long long get1(int x,int y) 44 { 45     long long ans=-1e17; 46     for(int i=y;i;i-=lowbit(i)) 47     { 48         ans=max(ans,B[x][i]); 49     } 50     return ans; 51 } 52 long long get2(int x,int y) 53 { 54     long long ans=-1e17; 55     for(int i=y;i;i-=lowbit(i)) 56     { 57         ans=max(ans,C[x][i]); 58     } 59     return ans; 60 } 61 long long que(int l,int r) 62 { 63     if(bel[l]==bel[r]) 64     { 65         long long ans=-1e17; 66         for(int i=l;i<=r;i  ) 67         { 68             ans=max(ans,get1(i,r)); 69         } 70         return ans; 71     } 72     long long ans=-1e17; 73     for(int i=l;i<st[bel[l] 1];i  ) 74     { 75         ans=max(ans,get1(i,r)); 76     } 77     for(int i=bel[l] 1;i<bel[r];i  ) ans=max(ans,get2(i,r)); 78     for(int i=st[bel[r]];i<=r;i  ) 79     { 80         ans=max(ans,get1(i,r)); 81     } 82     return ans; 83 } 84 int main() 85 { 86     scanf("%d%d",&n,&m); 87     for(int i=1;i<=n;i  ) 88     { 89         scanf("%d",&A[i]); 90     } 91     len=sqrt(n); 92     for(int i=1;i<=n;i  ) 93     { 94         bel[i]=(i-1)/len 1; 95         if(!st[bel[i]])st[bel[i]]=i; 96     } 97     for(int i=1;i<=n;i  ) 98     { 99         for(int j=0;j<=n;j  ) B[i][j]=C[i][j]=-1e17;100     }101     bel[n 1]=bel[n] 1;102     st[bel[n 1]]=n 1;103     for(int i=1;i<=n;i  )104     {105         long long ans=0;106         for(int j=i;j<=n;j  )107         {108             ans =A[j];109             T x;110             x.first=ans;111             x.second.first=i;112             x.second.second=j;113             q1.push(x);114         }115     }116     for(int i=1;i<=m;i  )117     {118         scanf("%d%d%lld",&q[i].l,&q[i].r,&q[i].data);119         q[i].bh=i;120     }121     sort(q 1,q m 1,cmp);122     for(int i=1;i<=m;i  )123     {124         while(!q1.empty()&&q1.top().first<=q[i].data)125         {126             T x=q1.top();q1.pop();127             add1(x.second.first,x.second.second,x.first);128             add2(bel[x.second.first],x.second.second,x.first);129         }130         ans[q[i].bh]=que(q[i].l,q[i].r);131     }132     for(int i=1;i<=m;i  )133     {134         if(ans[i]==-1e17)135             printf("NONE\n");136         else printf("%lld\n",ans[i]);137     }138     return 0;139 }140 /*141 2 1142 10000000000000000 -10000000000000000143 */

View Code

来源:https://www.icode9.com/content-4-862401.html

(0)

相关推荐

  • 树状数组及应用

    树状数组及应用

  • 编程语言树状数组小结

    前言 在近三周的时间内,我主要复习了线段树和树状数组.但是线段树在遇到一道压位黑题崩掉后就写不动了. 突发奇想,我决定给这段时间的复习内容写个总结.本蒟蒻实力有限,如果某些做法比较拉请谅解 本总结默认 ...

  • 2021黄浦、崇明二模25题解法分析(构造X/A基本图形)

    2021黄浦.崇明二模25题主要围绕着构造A/X型,构建两组比例关系,从而助力问题解决.这类问题中往往隐含着"燕尾模型",通过合理添加辅助线,构造基本图形,借助线段间的比例关系(一 ...

  • 【2021中考】一道相似压轴题解法微探

    <怎样解题>一书的作者匈牙利数学家波利亚说过,掌握数学就意味着要善于解题.做题不在多而在精,题要解得精彩:对待解题的思想方法要对头,要通过做题,深刻理解概念,扎实掌握基本知识,学会运筹帷幄 ...

  • 2021浦东二模25题解法分析

    2021浦东二模25题以圆内接四边形为背景,综合考察了圆与正多边形(中心角),相似三角形的证明和性质以及等腰三角形的存在性问题,整道题的难度不大,辅助线的添加方法也是常规的连半径或做高解直角三角形. ...

  • 2.七年级数学下册:这题解二元一次方程,没想到有这招,整体代入好简单

    欢迎您来到方老师数学课堂,请点击上方的名片,关注方老师数学课堂.所有的视频内容,全部免费,请大家放心关注,放心订阅. 七年级数学下册:这题解二元一次方程,没想到有这招,整体代入好简单.大家先在草稿本上 ...

  • 2021徐汇二模25题解法分析

    2021徐汇二模25题以cos∠BAC=3/5,围绕"动"正方形和"动"正三角形,主要围绕构造直角三角形,利用锐角三角比解决问题. 2021徐汇二模25题解题背 ...

  • 《高中数学考点题解》考点真题目录

    <高中数学考点题解> 考点真题目录 (点击链接可看相关考点真题)  <数列>考点真题目录 [考点1]等差数列的判断与证明--定义法 [考点2]通项公式的推导过程及运用--累加法 ...

  • 《高中数学考点题解》考点目录

    <高中数学考点题解> 考点目录 (点击链接可看相关考点)  <数列>考点目录 [考点1]等差数列的判断与证明--定义法 [考点2]通项公式的推导过程及运用--累加法[考点3]通 ...

  • 2021年高考数学——导数专题解答题题型...

    2021年高考数学--导数专题解答题题型训练(培优系列,值得学习) 1.函数单调性讨论问题 2.函数与导数不等式问题(参数分离.放缩法.极值点偏移.) 3.导数与数列型不等式证明 4.方程与零点问题

  • 2021嘉定二模25题解法分析

    2021嘉定二模25题解题背景:2021嘉定二模的25题虽然是圆的背景,但是主要围绕着平行线分线段成比例定理(图1),X型基本图形(图2),以及勾股定理和垂径定理结合展开,本题的第三问在(1)和(2) ...