题目连接:
https://ac.nowcoder.com/acm/contest/26896/1002
这个题好难哇,不会…看完题解只能说太妙啦!
分析
参考题解:
https://blog.nowcoder.net/n/5d56166fc2804d55b4f43f32d2aa42d6?f=comment
主要思想是能把多个数的查询转换成单点查询;
通过%k意义下就能做到固定x的值;
那么我们的区间也可以%k做到固定;
此时我们只需要查询x这个点有多少区间就行;
维护区间个数的话我们可以用 差分 + 树状数组维护前缀和 来搞;
由于树状数组维护的是类似下标的,所以要从1开始,即%k后要+1
这里注意当k=0时要单独考虑;
思想也是一样的,这里就不用通过%k去固定x了,x本身就是固定的;
我们只用维护一下区间就行,这里维护区间就要离散化一下了(因为1e9);
显然区间需要是有序的,所以我们要保序 (排序去重+二分)
由于需要离散化,因此我们需要离线操作…
代码
int n,k;
vector<int> v; //离散化
struct node
{
int op,l,r,x;
}no[maxn];
int tr[maxn];
void update(int x,int v)
{
while(x < maxn)
{
tr[x] += v;
x += lowbit(x);
}
}
int query(int x)
{
int ans = 0;
while(x)
{
ans += tr[x];
x -= lowbit(x);
}
return ans;
}
int getid(int x) //二分
{
return lower_bound(v.begin(),v.end(),x) - v.begin() + 1;
}
int main()
{
iire(n,k);
if(n == 0)
{
cout<<"fafa\n";
return 0;
}
for(int i=1;i<=n;i++)
{
int op,l,r,x;
ire(op);
if(op != 3)
{
iire(l,r);
v.push_back(l);
v.push_back(r);
no[i] = {op,l,r};
}
else
{
ire(x);
v.push_back(x);
no[i].op = 3;
no[i].x = x;
}
}
//离散化
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
if(k == 0)
{
for(int i=1;i<=n;i++)
{
int op = no[i].op;
int l = getid(no[i].l);
int r = getid(no[i].r);
int x = getid(no[i].x);
if(op == 1)
{
update(l,1);
update(r+1,-1);
}
else if(op == 2)
{
update(l,-1);
update(r+1,1);
}
else
{
cout<<query(x)<<'\n';
}
}
}
else
{
for(int i=1;i<=n;i++)
{
int op = no[i].op;
int l = no[i].l;
int r = no[i].r;
int x = no[i].x;
if(op == 1)
{
if(r - l + 1 >= k) //此时x无论为多少值都能覆盖这个区间
{
update(1,1);
update(k+1,-1);
}
else
{
l = (l % k + 1);
r = (r % k + 1);
if(l <= r)
{
update(l,1);
update(r+1,-1);
}
else //这里想不明白的考虑这个例子[8,11],k=5 => [4,2]
{
update(1,1);
update(r+1,-1);
update(l,1);
update(k+1,-1);
}
}
}
else if(op == 2)
{
if(r - l + 1 >= k)
{
update(1,-1);
update(k+1,1);
}
else
{
l = (l % k + 1);
r = (r % k + 1);
if(l <= r)
{
update(l,-1);
update(r+1,1);
}
else //这里想不明白的考虑这个例子[8,11],k=5 => [4,2]
{
update(1,-1);
update(r+1,1);
update(l,-1);
update(k+1,1);
}
}
}
else
{
x = (x % k + 1);
cout<<query(x)<<'\n';
}
}
}
return 0;
}