题意

显然商店编号的限制能用可持久化trie解决。

特殊的商品预先判掉就好了,现在只考虑普通的商品。

发现商品的时间是单点,询问时一段时间,于是将询问区间在线段树上拆成\(log\)个区间,分别放上该询问。

之后dfs整颗线段树,先计算当前节点上的询问,之后将商品按照出现时间是在中点左右分成两类递归。

code:

#include<bits/stdc++.h>
using namespace std;
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
const int maxn=1e5+10;
int n,m,cnt1,cnt2,tot,num;
int ans[maxn],root[maxn],cnt[maxn*40],a[maxn];
int trie[maxn*40][2];
struct Buy{int tim,x,k;}buy[maxn],tmp1[maxn],tmp2[maxn];
struct Query{int sl,sr,tl,tr,k;}qr[maxn];
vector<int>seg[maxn<<2];
inline bool cmp(Buy a,Buy b){return a.x<b.x;}
void insert(int pre,int& now,int t,int k)
{
now=++tot;
trie[now][0]=trie[pre][0];trie[now][1]=trie[pre][1];cnt[now]=cnt[pre]+1;
if(t<0)return;
int c=(k>>t)&1;
insert(trie[pre][c],trie[now][c],t-1,k);
}
int query(int pre,int now,int t,int k)
{
if(t<0)return 0;
int c=(k>>t)&1;
if(cnt[trie[now][c^1]]-cnt[trie[pre][c^1]])return (1<<t)|query(trie[pre][c^1],trie[now][c^1],t-1,k);
else return query(trie[pre][c],trie[now][c],t-1,k);
}
void change(int p,int l,int r,int ql,int qr,int id)
{
if(ql>qr)return;
if(l>=ql&&r<=qr){seg[p].push_back(id);return;}
int mid=(l+r)>>1;
if(ql<=mid)change(ls(p),l,mid,ql,qr,id);
if(qr>mid)change(rs(p),mid+1,r,ql,qr,id);
}
inline int find(int x)
{
int l=0,r=num,res;
while(l<=r)
{
int mid=(l+r)>>1;
if(a[mid]<=x)res=mid,l=mid+1;
else r=mid-1;
}
return res;
}
inline void calc(int p,int L,int R)
{
tot=num=0;
for(int i=L;i<=R;i++)
{
a[++num]=buy[i].x;
insert(root[num-1],root[num],18,buy[i].k);
}
for(unsigned int i=0;i<seg[p].size();i++)
{
int id=seg[p][i],l,r;
l=find(qr[id].sl-1),r=find(qr[id].sr);
ans[id]=max(ans[id],query(root[l],root[r],18,qr[id].k));
}
}
void solve(int p,int l,int r,int ql,int qr)
{
if(ql>qr)return;
calc(p,ql,qr);
if(l==r)return;
int mid=(l+r)>>1,cntl=0,cntr=0;
for(int i=ql;i<=qr;i++)
{
if(buy[i].tim<=mid)tmp1[++cntl]=buy[i];
else tmp2[++cntr]=buy[i];
}
for(int i=1;i<=cntl;i++)buy[ql+i-1]=tmp1[i];
for(int i=1;i<=cntr;i++)buy[ql+cntl+i-1]=tmp2[i];
solve(ls(p),l,mid,ql,ql+cntl-1);solve(rs(p),mid+1,r,ql+cntl,qr);
}
int main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
insert(root[i-1],root[i],18,x);
}
for(int i=1;i<=m;i++)
{
int op;scanf("%d",&op);
if(!op)
{
int x,k;scanf("%d%d",&x,&k);
cnt1++;buy[cnt1]=(Buy){cnt1,x,k};
}
else
{
int sl,sr,k,d;scanf("%d%d%d%d",&sl,&sr,&k,&d);
qr[++cnt2]=(Query){sl,sr,max(1,cnt1-d+1),cnt1,k};
ans[cnt2]=query(root[sl-1],root[sr],18,k);
}
}
for(int i=1;i<=cnt2;i++)change(1,1,cnt1,qr[i].tl,qr[i].tr,i);
sort(buy+1,buy+cnt1+1,cmp);
solve(1,1,cnt1,1,cnt1);
for(int i=1;i<=cnt2;i++)printf("%d\n",ans[i]);
return 0;
}

最新文章

  1. CentOS个人目录下中文路径转英文路径
  2. opencv用imread( argv[1], 1)读取图片
  3. mongoDB(3) mapReduce
  4. Unity3D中Console控制台的扩展
  5. [ALM]一步一步搭建MS ALM环境 - 安装TFS + SQL SERVER
  6. 未完全关闭数据库导致ORA-01012: not logged的解决
  7. MyEclipse 下用link 方式安装插件
  8. .NET Core多平台开发体验[1]: Windows
  9. ThoughtWorks的面试总结
  10. 不同系统下的字长------typedef的意义
  11. 转:【专题十一】实现一个基于FTP协议的程序——文件上传下载器
  12. kafka 基础知识梳理
  13. spring eureka required a bean of type &#39;com.netflix.discovery.DiscoveryClient&#39; that could not be found.
  14. Crawl(2)
  15. .NET(C#):使用反射来获取枚举的名称、值和特性
  16. Alpha阶段敏捷冲刺 ADY8
  17. Sping-Spring JDBC框架
  18. zookeeper和淘宝dubbo的关系
  19. Android MVC,MVP,MVVM模式入门——重构登陆注册功能
  20. 什么是hive

热门文章

  1. alipay sign error
  2. 洛谷 P5639 【CSGRound2】守序者的尊严
  3. 安装office2010出现的一些问题
  4. IDEA debug工具使用
  5. iOS: 线程中那些常见的锁
  6. 用Fastclick解决移动端300ms延迟问题
  7. Hbase内存磁盘大致关系
  8. Spring Boot配置过滤器的两种方式
  9. C#用Call代替CallVirt之后的测试用例
  10. python基础(27):类成员的修饰符、类的特殊成员