牛客ds题1002践踏

分析每个操作

操作一,加入一条线段[l,r],感觉可以直接懒标记,[l,r] tag+=1,也可以差分操作

操作二,删除一条线段[l,r],[l,r]tag-=1

操作三,x+kt=y,问y可以在几条线段内,t取整数,一开始想暴力,r<1e9,x=1,k=1e5,t最少也要循环到1e4,一次操作三就循环1e4,很明显不能暴力,分析x+kt=y这式子,先从简单的开始,k=0,那只需要查x的位置即可,如果k!=0,有什么办法只查一个位置呢,分析有贡献的线段可以把它们平移到[0,k-1]区间内,查x%k位置存在贡献,那就好办了

k=0,直接操作,查x的位置,n=1e5,离散化处理即可

k!=0,把线段平移到[0,k-1]即可,查x%k位置,线段树处理,线段平移到[1,k]区间内

线段平移处理(懒标记) M=1e5

1.r-l+1>=k 相当于[1,k]区间都被覆盖了 modify(1,1,M,1,k,1)

2.l>r  modify(1,1,M,1,r,1) modify(1,1,M,l,k,1)

3.r>l modify(1,1,M,l,r,1)

懒标记处理

// Problem: 践踏
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/26896/1002
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<algorithm>
#include<vector>
#define INF (1ll<<60)
using namespace std;
typedef long long ll;
const int N=1e5+9;
const int M=1e5;
int a[N];
struct node{
	ll val,tag;
}seg[N<<2];
struct Q{
	int op,l,r,x;
}que[N];
vector<int> X;
ll binary(int x){return lower_bound(X.begin(),X.end(),x)-X.begin()+1;}
ll tl(ll x){return x<<1;}
ll tr(ll x){return x<<1|1;}
bool inrange(int L,int R,int l,int r){
	return L>=l && R<=r;
}
bool outofrange(int L,int R,int l,int r){
	return L>r || l>R;
}
void pushup(int id){
	seg[id].val=seg[tl(id)].val+seg[tr(id)].val;
}
void maketag(int id,int l,int r,int v){
	seg[id].tag+=v;
	seg[id].val+=(r-l+1)*v;
}
void pushdown(int id,int l,int r){
	int mid=(l+r)>>1;
	maketag(tl(id),l,mid,seg[id].tag);
	maketag(tr(id),mid+1,r,seg[id].tag);
	seg[id].tag=0;
}
void modify(int id,int L,int R,int l,int r,int v){
	if(inrange(L,R,l,r)){
		maketag(id,L,R,v);
	}else if(!outofrange(L,R,l,r)){
		int mid=(L+R)>>1;
		pushdown(id,L,R);
		modify(tl(id),L,mid,l,r,v);
		modify(tr(id),mid+1,R,l,r,v);
		pushup(id);
	}
}

ll query(int id,int l,int r,int pos){
	if(l==r){
		return seg[id].val;
	}
	int mid=(l+r)>>1;
	pushdown(id,l,r);
	if(mid>=pos){
		return query(tl(id),l,mid,pos);
	}else{
		return query(tr(id),mid+1,r,pos);
	}
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
	int n,k;
	cin>>n>>k;
	if(!n){
		cout<<"fafa"<<'\n';
		return 0;
	}
	for(int i=1;i<=n;i++){
		cin>>que[i].op;
		if(que[i].op==1){
			cin>>que[i].l>>que[i].r;
			X.push_back(que[i].l);
			X.push_back(que[i].r);
		}else if(que[i].op==2){
			cin>>que[i].l>>que[i].r;
			X.push_back(que[i].r);
			X.push_back(que[i].l);
		}else{
			cin>>que[i].x;		
			X.push_back(que[i].x);
		}
	}
	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	if(!k){
		for(int i=1;i<=n;i++){
			if(que[i].op==1){
				int l,r;
				l=binary(que[i].l);
				r=binary(que[i].r);
				modify(1,1,M,l,r,1);
			}else if(que[i].op==2){
				int l,r;
				l=binary(que[i].l);
				r=binary(que[i].r);
				modify(1,1,M,l,r,-1);
			}else{
				int x;
				x=binary(que[i].x);
				cout<<query(1,1,M,x)<<'\n';
			}
		}
	}else{
		for(int i=1;i<=n;i++){
			if(que[i].op==1){
				if(que[i].r-que[i].l+1>=k){
					modify(1,1,M,1,k,1);
					continue;
				}
				int l=que[i].l%k;
				l++;
				int r=que[i].r%k;
				r++;
				if(l>r){
					modify(1,1,M,1,r,1);					
					modify(1,1,M,l,k,1);					
				}else{
					modify(1,1,M,l,r,1);
				}
			}else if(que[i].op==2){
				if(que[i].r-que[i].l+1>=k){
					modify(1,1,M,1,k,-1);
					continue;
				}
				int l=que[i].l%k;
				l++;
				int r=que[i].r%k;
				r++;
				if(l>r){
					modify(1,1,M,1,r,-1);					
					modify(1,1,M,l,k,-1);					
				}else{
					modify(1,1,M,l,r,-1);				
				}
			}else{
				int x=que[i].x%k;
				x++;
				cout<<query(1,1,M,x)<<'\n';
			}
		}
	}
    return 0;
}

差分处理

// Problem: 践踏
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/26896/1002
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
#include<algorithm>
#include<vector>
#define INF (1ll<<60)
using namespace std;
typedef long long ll;
const int N=1e5+9;
const int M=1e5;
int a[N];
struct node{
	ll val,tag;
}seg[N<<2];
struct Q{
	int op,l,r,x;
}que[N];
vector<int> X;
ll binary(int x){return lower_bound(X.begin(),X.end(),x)-X.begin()+1;}
ll tl(ll x){return x<<1;}
ll tr(ll x){return x<<1|1;}
bool inrange(int L,int R,int l,int r){
	return L>=l && R<=r;
}
bool outofrange(int L,int R,int l,int r){
	return L>r || l>R;
}
void pushup(int id){
	seg[id].val=seg[tl(id)].val+seg[tr(id)].val;
}
ll query(int id,int l,int r,int pos){
	if(l==r){
		return seg[id].val;
	}
	int mid=(l+r)>>1;
	if(mid>=pos){
		return query(tl(id),l,mid,pos);
	}else{
		return query(tr(id),mid+1,r,pos);
	}
}
ll ask(int id,int L,int R,int l,int r){
	if(inrange(L,R,l,r)){
		return seg[id].val;
	}else if(!outofrange(L,R,l,r)){
		int mid=(L+R)>>1;
		return ask(tl(id),L,mid,l,r)+ask(tr(id),mid+1,R,l,r);
	}else{
		return 0;
	}
}
void update(int id,int l,int r,int pos,int v){
	if(l==r){
		seg[id].val+=v;
		return;
	}
	int mid=(l+r)>>1;
	if(mid>=pos){
		update(tl(id),l,mid,pos,v);
	}else{
		update(tr(id),mid+1,r,pos,v);
	}
	pushup(id);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
	int n,k;
	cin>>n>>k;
	if(!n){
		cout<<"fafa"<<'\n';
		return 0;
	}
	for(int i=1;i<=n;i++){
		cin>>que[i].op;
		if(que[i].op==1){
			cin>>que[i].l>>que[i].r;
			X.push_back(que[i].l);
			X.push_back(que[i].r);
		}else if(que[i].op==2){
			cin>>que[i].l>>que[i].r;
			X.push_back(que[i].r);
			X.push_back(que[i].l);
		}else{
			cin>>que[i].x;		
			X.push_back(que[i].x);
		}
	}
	sort(X.begin(),X.end());
	X.erase(unique(X.begin(),X.end()),X.end());
	if(!k){
		for(int i=1;i<=n;i++){
			if(que[i].op==1){
				int l,r;
				l=binary(que[i].l);
				r=binary(que[i].r);
				update(1,1,M,l,1);
				update(1,1,M,r+1,-1);
			}else if(que[i].op==2){
				int l,r;
				l=binary(que[i].l);
				r=binary(que[i].r);
				update(1,1,M,l,-1);
				update(1,1,M,r+1,1);
			}else{
				int x; 
				x=binary(que[i].x);
				cout<<ask(1,1,M,1,x)<<'\n';
			}
		}
	}else{
		for(int i=1;i<=n;i++){
			if(que[i].op==1){
				if(que[i].r-que[i].l+1>=k){
					update(1,1,M,1,1);
					update(1,1,M,k+1,-1);
					continue;
				}
				int l=que[i].l%k;
				l++;
				int r=que[i].r%k;
				r++;
				if(l>r){
					update(1,1,M,1,1);				
					update(1,1,M,r+1,-1);	
					update(1,1,M,l,1);				
					update(1,1,M,k+1,-1);				
				}else{
					update(1,1,M,l,1);
					update(1,1,M,r+1,-1);
				}
			}else if(que[i].op==2){
				if(que[i].r-que[i].l+1>=k){
					update(1,1,M,1,-1);
					update(1,1,M,k+1,1);
					continue;
				}
				int l=que[i].l%k;
				l++;
				int r=que[i].r%k;
				r++;
				if(l>r){
					update(1,1,M,1,-1);				
					update(1,1,M,r+1,1);	
					update(1,1,M,l,-1);				
					update(1,1,M,k+1,1);				
				}else{
					update(1,1,M,l,-1);
					update(1,1,M,r+1,1);
				}
			}else{
				int x=que[i].x%k;
				x++;
				cout<<ask(1,1,M,1,x)<<'\n';
			}
		}
	}
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值