分析每个操作
操作一,加入一条线段[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;
}