正题

题目链接:https://www.luogu.com.cn/problem/P7470


题目大意

给出\(n\)个二元组\((a,b)\)。

\(q\)次询问给出\((l,r,c,d)\)表示询问\([l,r]\)中有多少二元组满足\(c\ xor\ a\leq min(b,d)\)。

\(1\leq n,q\leq 10^5\)


解题思路

这个\(min\)一看就很迷,显然是让我们分两种情况讨论。

再把询问拆一下,就变成了两个条件\(pos\leq r/pos<l\)且\(b\leq d/b>d\)。

两个偏序条件的话直接上\(CDQ\),然后考虑两种情况怎么处理。

  • \(c\ xor\ a\leq b\):这样对于每个二元组合法的\(c\)开业被拆成\(Trie\)上最多\(log\)个区间,建\(Trie\)即可
  • \(c\ xor\ a\leq d\):对于每组询问在\(Trie\)上跑区间求和即可。

时间复杂度\(O(n\log^2 n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=1e5+10,M=N*24;
struct node{
int w,l,id;
}q[N<<1],a[N];
int n,m,tot,rt1,rt2,ans[N];
vector<node> v[N];
struct Trie1{
int cnt,ch[M][2],w[M];
void Clear(){rt1=0;cnt=0;return;}
int Newp(){++cnt;ch[cnt][0]=ch[cnt][1]=w[cnt]=0;return cnt;}
void Insert(int &x,int d,int l,int val){
if(!x)x=Newp();
if(d<0){w[x]++;return;}
int c=(val>>d)&1;
if((l>>d)&1){
Insert(ch[x][c^1],d-1,l,val);
if(!ch[x][c])ch[x][c]=Newp();
w[ch[x][c]]++;
}
else Insert(ch[x][c],d-1,l,val);
}
int Ask(int x,int d,int val){
if(!x)return 0;
if(d<0)
return w[x];
int c=(val>>d)&1;
return Ask(ch[x][c],d-1,val)+w[x];
}
}T1;
struct Trie2{
int cnt,ch[M][2],w[M];
void Clear(){rt2=0;cnt=0;return;}
int Newp(){++cnt;ch[cnt][0]=ch[cnt][1]=w[cnt]=0;return cnt;}
void Insert(int &x,int d,int val){
if(!x)x=Newp();
if(d<0){w[x]++;return;}
int c=(val>>d)&1;
Insert(ch[x][c],d-1,val);
w[x]=w[ch[x][0]]+w[ch[x][1]];
return;
}
int Ask(int x,int d,int l,int val){
if(d<0)return w[x];
int c=(val>>d)&1;
if((l>>d)&1)
return Ask(ch[x][c^1],d-1,l,val)+w[ch[x][c]];
return Ask(ch[x][c],d-1,l,val);
}
}T2;
bool cmp(node x,node y)
{return x.l<y.l;}
void CDQ(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
CDQ(l,mid);
CDQ(mid+1,r);
sort(a+l,a+mid+1,cmp);
T1.Clear();T2.Clear();tot=0;
for(int i=mid+1;i<=r;i++)
for(int j=0;j<v[i].size();j++)
q[++tot]=v[i][j];
sort(q+1,q+1+tot,cmp);
for(int i=1,z=l;i<=tot;i++){
while(z<=mid&&a[z].l<=q[i].l)
T1.Insert(rt1,23,a[z].l,a[z].w),z++;
if(q[i].id<0)ans[-q[i].id]-=T1.Ask(rt1,23,q[i].w);
else ans[q[i].id]+=T1.Ask(rt1,23,q[i].w);
}
for(int i=tot,z=mid;i>=1;i--){
while(z>=l&&a[z].l>q[i].l)
T2.Insert(rt2,23,a[z].w),z--;
if(q[i].id<0)ans[-q[i].id]-=T2.Ask(rt2,23,q[i].l,q[i].w);
else ans[q[i].id]+=T2.Ask(rt2,23,q[i].l,q[i].w);
}
return;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].w,&a[i].l);
for(int i=1;i<=m;i++){
int l,r,c,d;
scanf("%d%d%d%d",&l,&r,&c,&d);
v[l].push_back((node){c,d,-i});
v[r+1].push_back((node){c,d,i});
}
sort(q+1,q+1+n,cmp);
CDQ(1,n+1);
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
return 0;
}

P7470-[NOI Online 2021 提高组]岛屿探险【Trie,CDQ分治】的更多相关文章

  1. [NOI Online 2021 提高组] 积木小赛

    思路不说了. 想起来自己打比赛的时候,没睡好.随便写了个\(HASH\),模数开小一半分都没有. 然后学了\(SAM\),发现这个判重不就是个水题. \(SAM\)是字串tire的集合体. 随便\(d ...

  2. CCF NOI Online 2021 提高组 T3 岛屿探险(CDQ 分治,Trie 树)

    题面 凇睦是一个喜欢探险的女孩子,这天她到一片海域上来探险了. 在这片海域上一共有 n 座岛屿排成一排,标号为 1, 2, 3, . . . , n.每座岛屿有两个权值,分别为劳累度 ai 和有趣度 ...

  3. CCF NOI Online 2021 提高组 赛后心得

    T1 做个,不会,拿到 20 pts 跑路. 注意后面有个 K = 1 的部分分,这个可以递推求 b 的个数,然后直接乘上 a0 . 官方正解讲得极其详细,我还是第一次见到可以 O(K2) 做 1~n ...

  4. CCF NOI Online 2021 提高组 T2 积木小赛 (子序列自动机+后缀自动机,O(n^2))

    题面 Alice 和 Bob 最近热衷于玩一个游戏--积木小赛. Alice 和 Bob 初始时各有 n 块积木从左至右排成一排,每块积木都被标上了一个英文小写字母. Alice 可以从自己的积木中丢 ...

  5. luogu P6570 [NOI Online #3 提高组]优秀子序列 二进制 dp

    LINK:P6570 [NOI Online #3 提高组]优秀子序列 Online 2的T3 容易很多 不过出于某种原因(时间不太够 浪了 导致我连暴力的正解都没写. 容易想到 f[i][j]表示前 ...

  6. P7473 [NOI Online 2021 入门组] 重力球

    P7473 [NOI Online 2021 入门组] 重力球 题意 给你一个正方形平面,某些位置有障碍,对于平面上两个球,每次你可以改变重力方向使两个球下落到最底端,求使两个球位置重合的最小改变重力 ...

  7. [NOI Online #2 提高组]涂色游戏 题解

    题目描述 你有 1020 个格子,它们从 0 开始编号,初始时所有格子都还未染色,现在你按如下规则对它们染色: 编号是 p1 倍数的格子(包括 0号格子,下同)染成红色. 编号是 p2 倍数的格子染成 ...

  8. NOI Online #2 提高组 游戏

    没用二项式反演的菜比. 题目链接 Solution 非平局代表的树上祖先关系是比较好统计,(可以在处理一个点时,考虑用他去匹配他的子树中的东西)而平局的关系比较难统计.我们不妨求出至少 \(k\) 个 ...

  9. NOI Online #2 提高组 游记

    没 NOI Online 1 挂的惨就来写游记吧,不知道为啥 NOI Online 1 民间数据测得 60 分的 T1 最后爆零了... 昏昏沉沉的醒来,吃了早饭,等到 \(8:30\) 进入比赛网页 ...

随机推荐

  1. js继承函数封装

    function extend(subClass,superClass) { //初始化一个中间空对象,为了转换主父类关系 var F = function() {}; F.prototype = s ...

  2. mybatis学习日志一

    Mybatis 介绍 MyBatis 是支持 普通 SQL 查询 , 存储过程 和 高级映射 的优秀持久层框架.MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以 及对结果集的检索封装 ...

  3. 一 MongoDB入门

    一.MongoDB概念解析(对比MySQL学习): 举个例子: MongoDB可视化操作工具:推荐Robomongo 二.MongoDB默认的概念: 1.MongoDB的单个实例可以容纳多个独立的数据 ...

  4. SpringCloud商品服务调用方式之Ribbon

    1.创建order_service项目 pom依赖 <dependency> <groupId>org.springframework.boot</groupId> ...

  5. Python - 面向对象编程 - 子类方法的重写

    继承的详解 https://www.cnblogs.com/poloyy/p/15216652.html 方法的重写 在子类继承父类时,子类会拥有父类的所有属性和方法 但当父类的方法实现不满足子类需要 ...

  6. C# 实现图片上传

    C# 实现图片上传 C#实现图片上传: 通过页面form表单提交数据到动作方法,动作方法实现保存图片到指定路径,并修改其文件名为时间格式 页面设置 这里使用的模板MVC自带的模板视图 <h2&g ...

  7. 【曹工杂谈】Maven源码调试工程搭建

    Maven源码调试工程搭建 思路 我们前面的文章<[曹工杂谈]Maven和Tomcat能有啥联系呢,都穿打补丁的衣服吗>分析了Maven大体的执行阶段,主要包括三个阶段: 启动类阶段,负责 ...

  8. 控制台:控制台艺术字 & 为控制台输出增加样式(console.log( ))

    控制台/代码文档LOGO 除了知乎的控制台,大部分的代码文档都有这样的字符logo. 下面这个网站可以自动生成符号艺术字: Text to ASCII Art Generator (TAAG) 控制台 ...

  9. elementui table的新增,编辑和删除

    \ 新增 this.tableData.unshift(data); 编辑 this.$set(this.tableData,data.index,data); 删除 rows.splice(inde ...

  10. RMI源码调试

    看RMI漏洞时候,对其漏洞原理并不是很理解,所以简单调试了下源码加强下漏洞理解 由于要调试到RegistryImpl_Stub这种动态类,刚开始用的源码版本是JDK8u141,后来发现源码有些地方进行 ...