当前位置:网站首页>Codeforces Round #810 (Div. 2) D. Rain (线段树差分)
Codeforces Round #810 (Div. 2) D. Rain (线段树差分)
2022-07-29 04:03:00 【Snow_raw】
Codeforces Round #810 (Div. 2) D. Rain (线段树差分)
前言: 一道恶心了我近一天的题,共 180 180 180 行重复敲了 3 3 3 次 , 不知道 d d d 了多久的 b u g bug bug ,还是线段树专题做的太少了。
题意: 给定一个 n n n ,这 n n n 天会降雨,每一个降雨天有一个 x x x 和一个 p p p ,表示自 x x x 为中心,降雨量向左右两边递减,例如 x = 3 x=3 x=3 、 p = 5 p=5 p=5 的情况为:
0 1 2 3 4 5 4 3 2 1 0
-2 -1 0 1 2 3 4 5 6 7 8
问:统计将任意一天天气变成非降雨天,所有地的最大降雨量是否不超过 m m m ,不超过输出 1 1 1 否则输出 − 1 -1 −1
思路: 首先本题很明显得知具有差分性,即降雨中心向左右两边以公差 d = 1 d=1 d=1 逐步递减,通过 无聊的数列(经典线段树差分) 可知我们可以在 O ( n l o g n ) O(nlogn) O(nlogn) 的时间复杂度内计算出这 n n n 天都下雨情况下所有降雨中心的 降雨值 这可以通过一个线段树实现。剩下的步骤就是枚举 1 1 1 ~ n n n 中的某一天不降雨情况下,所有地的降雨最大值是否小于 m m m ,我们开第二棵线段树用来维护三个最大值即 h [ l ] 、 h [ l ] − v e c [ l ] 、 h [ l ] + v e c [ l ] h[l]、h[l]-vec[l]、h[l]+vec[l] h[l]、h[l]−vec[l]、h[l]+vec[l] 其中第一个 h [ l ] h[l] h[l]表示不被当前枚举的降雨天所涉及情况下各地中降雨的最大值,因为降水量不会减少 。 其余两个分别是上坡与下坡的 偏移量写法 ,用来将同一斜线上的数置于同一水平上比较,得出区间降水最大值。
代码:
/* * @author: Snow * @Description: Algorithm Contest * @LastEditTime: 2022-07-27 10:51:20 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
#pragma GCC optimize(3)
#define re register int
typedef pair<int,int>PII;
#define pb emplace_back
#define debug(a) cout<<a<<' ';
#define fer(i,a,b) for(re i=a;i<=b;i++)
#define der(i,a,b) for(re i=a;i>=b;i--)
int n,m;
const int N = 2e5+10;
int x[N],p[N];
vector<int>vec2;
int vec[N*4];
int h[N*4];
char ans[N];
struct Seg_tree1{
struct Node{
int l,r,k,d;
}tr[N*16];
void build(int u,int l,int r){
if(l==r){
tr[u]={
l,r,0,0};
}
else{
int mid=l+r>>1;
tr[u]={
l,r};
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
}
void pushdown(int u){
if(tr[u].k||tr[u].d){
int mid=tr[u].l+tr[u].r>>1;
tr[u<<1].k+=tr[u].k;
tr[u<<1|1].k+=tr[u].k+(vec[tr[u<<1|1].l]-vec[tr[u].l])*tr[u].d;
tr[u<<1].d+=tr[u].d;
tr[u<<1|1].d+=tr[u].d;
tr[u].d=tr[u].k=0;
}
}
void modify(int u,int l,int r,int k,int d){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].k+=k+(vec[tr[u].l]-vec[l])*d;
tr[u].d+=d;
}
else{
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)modify(u<<1,l,r,k,d);
if(r>mid)modify(u<<1|1,l,r,k,d);
}
}
void floor(int u){
if(tr[u].l==tr[u].r){
h[tr[u].l]=tr[u].k;
}
else{
pushdown(u);
floor(u<<1);
floor(u<<1|1);
}
}
}seg1;
struct Seg_tree2{
struct Node{
int l,r,v1,v2,v3;
}tr[N*16];
void pushup(int u){
tr[u].v1=max(tr[u<<1].v1,tr[u<<1|1].v1);
tr[u].v2=max(tr[u<<1].v2,tr[u<<1|1].v2);
tr[u].v3=max(tr[u<<1].v3,tr[u<<1|1].v3);
}
void build(int u,int l,int r){
if(l==r){
tr[u]={
l,r,h[l],h[l]-vec[l],h[l]+vec[l]};
}
else{
tr[u]={
l,r};
int mid=l+r>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
}
Node query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r){
return tr[u];
}
int mid=tr[u].l+tr[u].r>>1;
if(r<=mid)return query(u<<1,l,r);
if(l>mid)return query(u<<1|1,l,r);
Node res;
Node left=query(u<<1,l,r);
Node right=query(u<<1|1,l,r);
res.v1=max(left.v1,right.v1);
res.v2=max(left.v2,right.v2);
res.v3=max(left.v3,right.v3);
return res;
}
}seg2;
void cf(){
vec2.clear();
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>x[i]>>p[i];
for(int i=1;i<=n;i++){
vec2.push_back(x[i]);
vec2.push_back(x[i]-p[i]+1);
vec2.push_back(x[i]+1);
vec2.push_back(x[i]+p[i]-1);
}
sort(vec2.begin(),vec2.end());
vec2.erase(unique(vec2.begin(),vec2.end()),vec2.end());
for(int i=1;i<=vec2.size();i++)vec[i]=vec2[i-1];
int len=vec2.size();
seg1.build(1,1,len);
for(int i=1;i<=n;i++){
int l=lower_bound(vec+1,vec+1+len,x[i]-p[i]+1)-vec;
int r=lower_bound(vec+1,vec+1+len,x[i])-vec;
if(l<=r){
seg1.modify(1,l,r,1,1);
}
l=lower_bound(vec+1,vec+1+len,x[i]+1)-vec;
r=lower_bound(vec+1,vec+1+len,x[i]+p[i]-1)-vec;
if(l<=r){
seg1.modify(1,l,r,p[i]-1,-1);
}
}
seg1.floor(1);
seg2.build(1,1,len);
fer(i,1,n){
int maxv=0;
int l=lower_bound(vec+1,vec+1+len,x[i]-p[i]+1)-vec;
int r=lower_bound(vec+1,vec+1+len,x[i])-vec;
if(l>1){
int t=seg2.query(1,1,l-1).v1;
maxv=max(maxv,t);
}
if(l<=r){
int t=seg2.query(1,l,r).v2;
maxv=max(maxv,t+vec[l]-1);
}
l=lower_bound(vec+1,vec+1+len,x[i]+1)-vec;
r=lower_bound(vec+1,vec+1+len,x[i]+p[i]-1)-vec;
if(r+1<=len){
int t=seg2.query(1,r+1,len).v1;
maxv=max(maxv,t);
}
if(l<=r){
int t=seg2.query(1,l,r).v3;
maxv=max(maxv,t-vec[r]-1);
}
ans[i]=maxv<=m?'1':'0';
}
fer(i,1,n)cout<<ans[i];
cout<<endl;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int _=1;
cin>>_;
while(_--){
cf();
}
return 0;
}
边栏推荐
- Typescript from getting started to mastering (XX) function generics
- Typescript from entry to mastery (XXI) generic types in classes
- Who can elaborate on the semi consistent read under mysqlrc and how to reduce the deadlock probability?
- 小马智行进军前装量产,从自研域控制器入手?
- UCOS task switching process
- 通过PWM呼吸灯和PWM控制直流电机来详细介绍TIM的输出比较功能
- Shopify卖家:EDM营销就要搭配SaleSmartly,轻松搞定转化率
- 关于双指针的思想总结
- Common methods of lodash Library
- MySQL第四篇(完结)
猜你喜欢

小马智行进军前装量产,从自研域控制器入手?

Simple cases of inner connection and left connection

Is the array name a pointer

Function pointer and callback function

mmdetection初步使用

The digitalization of the consumer industry is upgraded to "rigid demand", and weiit's new retail SaaS empowers enterprises!

Shopify seller: EDM marketing should be combined with salesmartly to easily get the conversion rate

Is the browser multi process or single process?

LVS+KeepAlived高可用部署实战应用

UCOS task switching process
随机推荐
Asp. Net MVC, how can the controller in the folder jump to the controller in the root directory?
大佬们flink的JDBC SQL Connector现在不支持所有的数据库吗,例如vertica?
First ALV program 2
Is the array name a pointer
Typescript from getting started to mastering (XXII) namespace namespace (I)
1985-2020 (8 Editions) global surface coverage download and introduction
Analysis of new retail o2o e-commerce model
从2019 年开始,你一定停止使用了这个营销策略…
A little understanding of pointer, secondary pointer, wild pointer, pointer as function return value
企业网的三层架构
Shopify seller: EDM marketing should be combined with salesmartly to easily get the conversion rate
Deconstruction assignment of new features of ES6
3. Solve pychart's error unresolved reference 'selenium' unresolved reference 'webdriver‘
Object array merges elements according to a field
Some notes on uniapp
Value transmission and address transmission of C language, pointer of pointer
Batch production and upload sales NFT opensea eth polygon
C language - character array - string array - '\0' -sizeof-strlen() -printf()
VScode连接ssh遇到的问题
nacos注册中心