玲珑杯” Round #19 Buildings 【线段树+尺取法】+【vector + 尺取法】
来源:互联网 发布:mac系统误删文件 编辑:程序博客网 时间:2024/06/05 14:42
第一种 线段树(维护区间的最大值和最小值)+尺取法
#include<bits/stdc++.h>#define LL long long#define lele o<<1#define riri o<<1|1#define lson o<<1,le,mid#define rson o<<1|1,mid+1,riusing namespace std;const int MAXN =2*1e5+10;struct Tree{ int l,r; int maxx; int minn;}tree[MAXN<<2];int n,k;void pushup(int o){ tree[o].maxx=max(tree[lele].maxx,tree[riri].maxx); tree[o].minn=min(tree[lele].minn,tree[riri].minn);}void build(int o,int le,int ri){ tree[o].l=le;tree[o].r=ri; if(le==ri) { int val;scanf("%d",&val); tree[o].maxx=tree[o].minn=val; return ; } int mid =(le+ri)>>1; build(lson); build(rson); pushup(o);} int querymax(int o,int le,int ri) { if(le<=tree[o].l&&ri>=tree[o].r) return tree[o].maxx; int mid=(tree[o].l+tree[o].r)>>1; if(ri<=mid) querymax(lele,le,ri); else if(le>mid ) querymax(riri,le,ri); else return max(querymax(lele,le,mid),querymax(riri,mid+1,ri)); } int querymin(int o,int le,int ri) { if(le<=tree[o].l&&ri>=tree[o].r) return tree[o].minn; int mid=(tree[o].l+tree[o].r)>>1; if(ri<=mid) querymin(lele,le,ri); else if(le>mid ) querymin(riri,le,ri); else return min(querymin(lele,le,mid),querymin(riri,mid+1,ri)); }int main(){ while(scanf("%d%d",&n,&k)!=EOF){ build(1,1,n); int le=1;int ri=1; LL sum=0; for(;ri<=n&&le<n;){ // 尺取法 while((querymax(1,le,ri)-querymin(1,le,ri))>k) le++; sum+=(LL)(ri-le); ri++; } printf("%lld\n",sum+n); } return 0;}
分析 二
可以用vector来维护区间的有序性,从而找到最大值和最小值,从而尺取法解。
代码
#include<bits/stdc++.h>#define LL long longusing namespace std;const int MAXN =1e6+100;int arr[MAXN];vector<int>ve;int main(){ int n,k; while(scanf("%d%d",&n,&k)!=EOF){ ve.clear(); for(int i=1;i<=n;i++) scanf("%d",&arr[i]); if(n==1) {puts("1");continue;} int le,ri; le=ri=1; ve.push_back(arr[1]); int siz=1; LL sum=0; for(int i=2;i<=n;i++){ ri=i; int ans=lower_bound(ve.begin(),ve.end(),arr[ri])-ve.begin(); ve.insert(ve.begin()+ans,arr[ri]); siz++; while(ve[siz-1]-ve[0]>k){ ans=lower_bound(ve.begin(),ve.end(),arr[le++])-ve.begin(); ve.erase(ve.begin()+ans); siz--; } sum+=(LL)(ri-le); //如果(max-min)<=k 那么max和区间里的所有值的差肯定也都小于等于k } printf("%lld\n",sum+n); //最后加上自身的区间一定是小于等于k的 } return 0;}
阅读全文
0 0
- 玲珑杯” Round #19 Buildings 【线段树+尺取法】+【vector + 尺取法】
- “玲珑杯”线上赛 Round #15 咸鱼魔法记(尺取法)
- CSU 1553 线段树+尺取法
- 玲珑杯round#19B 1149 Buildings
- 尺取法
- 尺取法
- 尺取法
- 尺取法
- 尺取法
- 尺取法
- 尺取法
- 尺取法
- 【尺取法】
- 尺取法
- 尺取法
- 尺取法
- 尺取法
- 尺取法
- shell命令--ln
- python变量作用域
- 棋盘问题(深度搜索)
- HDU 2709 Sumsets —— 递推
- HDU 4526 威威猫系列故事——拼车记 dp
- 玲珑杯” Round #19 Buildings 【线段树+尺取法】+【vector + 尺取法】
- Java 8 Streams map()
- Bean感知Spring容器
- BZOJ 3998 弦论 (后缀自动机)
- JDK 动态代理执行流程解析
- RxJava学习笔记
- 【Android】获取QQ的信息
- UVA
- 写博客的重要性