列表

详情


NC21125. 践踏

描述

首先给定一个定值k,支持如下操作(在数轴上)
1. 加入一条线段[l,r]
2. 删除一条已经存在的线段
3. 给定x,问有多少个区间包含x+kt,其中t是一个整数变量,即t ∈ Z
比如说当x=2,k=3的时候,区间[7,10]是应该算入答案的,因为x+2k=8,且7 ≤ 8 ≤ 10
如果n=0,那么你只需要输出一行"fafa"然后结束程序即可(注意不输出双引号)

输入描述

第一行两个整数n,k,分别表示操作次数以及定值k
之后有n行,每行先输入一个整数op,之后分类讨论:
1. op=1,此时再输入[l,r],表示加入一个区间[l,r]
2. op=2,此时再输入[l,r],表示删除区间[l,r],保证这个区间存在(如果存在多个相同的区间,那么只需要删除其中的任意一个)
3. op=3,此时再输入x,之后需要输出答案并换行

输出描述

对于每一个op=3的操作,输出查询结果后换行

示例1

输入:

10 7
1 3393 14151
3 13229
1 3427 18356
1 7602 20138
1 8566 28714
1 1076 32552
2 3427 18356
2 8566 28714
3 10962
1 387 7783

输出:

1
3

说明:

(以下内容与本题无关)
这个样例,无疑是善良的出题人无私的馈赠。
大量精心构造的 n ≤ 100 的测试数据,涵盖了测试点中所有出现性质的组合。
你可以利用这个测试点,对自己的程序进行全面的检查。
足量的数据组数、不大的数据范围和多种多样的数据类型,能让程序中的错误无处遁形。
出题人相信,这个美妙的样例,可以给拼搏于 AC 这道题的逐梦之路上的你,提供一个有力的援助。

示例2

输入:

0 0

输出:

fafa

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 69ms, 内存消耗: 2852K, 提交时间: 2019-07-15 20:54:49

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int tr[maxn],num[2*maxn];
struct node
{
	int o,l,r,x;
}q[maxn];
int n;
void updata(int l,int r,int val)
{
	for(int i=l;i<maxn;i+=i&-i){
		tr[i]+=val;
	}
	for(int i=r+1;i<maxn;i+=i&-i){
		tr[i]-=val;
	}
}
int query(int x)
{
	int rec=0;
	while(x){
		rec+=tr[x];
		x-=x&-x;
	}
	return rec;	
}
int main()
{
	int k,o,l,r,x;
	scanf("%d%d",&n,&k);
	if(n==0){
		printf("fafa\n");
		return 0;
	}
	int cnt=0;
	if(k==0){
		for(int i=1;i<=n;i++){
			scanf("%d",&o);
			if(o==1||o==2){
				scanf("%d%d",&l,&r);
				num[++cnt]=l;
				num[++cnt]=r;
				q[i].l=l;q[i].o=o;q[i].r=r;
			}
			else{
				scanf("%d",&x);
				num[++cnt]=x;
				q[i].o=o;q[i].x=x;
			}
		}
		sort(num+1,num+cnt+1);
		cnt=unique(num+1,num+cnt+1)-num-1;
		for(int i=1;i<=n;i++)
		{
			if(q[i].o==1){
				l=lower_bound(num+1,num+cnt+1,q[i].l)-num;
				r=lower_bound(num+1,num+cnt+1,q[i].r)-num;
				updata(l,r,1);
			}
			else if(q[i].o==2){
				l=lower_bound(num+1,num+cnt+1,q[i].l)-num;
				r=lower_bound(num+1,num+cnt+1,q[i].r)-num;
				updata(l,r,-1);
			}
			else{
				x=lower_bound(num+1,num+cnt+1,q[i].x)-num;
				printf("%d\n",query(x));
			}
		}
	}
	else{
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&o);
			if(o==1){
				scanf("%d%d",&l,&r);
				if(r-l+1>=k){
					updata(1,k,1);
				}
				else{
					l=l%k+1;
					r=r%k+1;
					if(l>r){
						updata(1,r,1);
						updata(l,k,1);
					}
					else
						updata(l,r,1);
				}
			}
			else if(o==2){
				scanf("%d%d",&l,&r);
				if(r-l+1>=k)
					updata(1,k,-1);
				else{
					l=l%k+1;
					r=r%k+1;
					if(l>r){
						updata(1,r,-1);
						updata(l,k,-1);
					}
					else
						updata(l,r,-1);
				}
			}
			else{
				scanf("%d",&x);
				x=x%k+1; 
				printf("%d\n",query(x));
			}
		}
	}
}

C++(g++ 7.5.0) 解法, 执行用时: 149ms, 内存消耗: 2084K, 提交时间: 2022-11-29 19:16:57

#include<bits/stdc++.h>
using namespace std;
struct FenWick {
  int lowbit(int x) {return x&-x;}
  vector<int> S;
  int N;
  FenWick(int N) { init(N); }
  void init(int N) {
    this->N = N;
    S.clear(); S.resize(N+1);
  }
  void add(int i, int x) {
    while (i <= N) S[i] += x, i += lowbit(i);
  }
  int64_t sum(int i) {
    int64_t tot = 0;
    while (i) tot += S[i], i -= lowbit(i);
    return tot;
  }
};


int main(){
  int n, k; cin >> n >> k;
  if (n == 0) {
    cout << "fafa" << endl;
    return 0;
  }
  FenWick F(k?k+1:123456);
  while (n--) {
    int op; cin >> op;
    if (op == 3) {
      int x; cin >> x; 
      if(k) x %= k;
      if (x > F.N) cout << 0 << endl;
      else  cout << F.sum(x+1)  << endl;
    } else {
      int inc = op == 1?1: -1;
      int l, r; cin >> l >> r;
      r++;
      if (k&&r - l >= k) {
        F.add(1, inc);
      } else {
        if (k) l%=k, r%=k;
        l++, r++;
        if (l < r) {
          F.add(l, inc);
          F.add(r, -inc);
        } else {
          F.add(1, inc);
          F.add(r, -inc);
          F.add(l, inc);
        }
      }
    }
  }
  
}

C++11(clang++ 3.9) 解法, 执行用时: 77ms, 内存消耗: 2524K, 提交时间: 2019-09-30 16:35:51

#include<bits/stdc++.h>
using namespace std;
#define M 100005
#define N 200005
int n,k,op,i,l,r,ans,res,c[N],b[N],si;
struct node {
	int op,l,r;
} a[M];
int sum(int x) {
	x++;
	int res=0;
	while(x)res+=c[x],x-=x&-x;
	return res;
}
void add(int x,int d) {
	x++;
	while(x<N)c[x]+=d,x+=x&-x;
}
int find(int x) {
	return lower_bound(b+1,b+si+1,x)-b;
}
int main() {
	scanf("%d%d",&n,&k);
	if(!n)printf("fafa\n");
	else if(!k) {
		for(i=1; i<=n; i++) {
			scanf("%d%d",&a[i].op,&a[i].l),b[++si]=a[i].l;
			if(a[i].op<3)scanf("%d",&a[i].r),b[++si]=a[i].r;
		}
		sort(b+1,b+si+1),si=unique(b+1,b+si+1)-b-1;
		for(i=1; i<=n; i++)
			if(a[i].op==3)printf("%d\n",sum(find(a[i].l)));
			else op=a[i].op==1?1:-1,add(find(a[i].l),op),add(find(a[i].r)+1,-op);
	} else {
		for(i=1; i<=n; i++) {
			scanf("%d%d",&op,&l);
			if(op==3)printf("%d\n",res+sum(l%k));
			else {
				if(op==2)op=-1;
				scanf("%d",&r);
				if(r-l+1>=k)res+=op;
				else {
					r%=k,l%=k;
					if(l<=r)add(l,op),add(r+1,-op);
					else add(l,op),add(r+1,-op),add(0,op);
				}
			}
		}
	}
	return 0;
}

上一题