bzoj 4571 [Scoi2016]美味——主席树

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4571

按位考虑,需要的就是一个区间;比如最高位就是(2^k -x)。

对于不是最高位的位置该怎么考虑?其实之前位置如果能或不能匹配上,也就相当于指定了之前的位上的是0还是1;把是1的位累计进一个变量里,加到区间的边界上就行了!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+5,M=1e5+5,K=N*20;
int n,m,mx,a[N],rt[N],tot,sm[K],ls[K],rs[K];
int ans,lj,lo,hi,bin[20];
int rdn()
{
    int ret=0;bool fx=1;char ch=getchar();
    while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)fx=0;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘) ret=(ret<<3)+(ret<<1)+ch-‘0‘,ch=getchar();
    return fx?ret:-ret;
}
void build(int &cr,int pre,int l,int r,int v)
{
    cr=++tot; ls[cr]=ls[pre]; rs[cr]=rs[pre];
    sm[cr]=sm[pre]+1;
    if(l==r) return; int mid=l+r>>1;
    if(v<=mid) build(ls[cr],ls[pre],l,mid,v);
    else build(rs[cr],rs[pre],mid+1,r,v);
}
bool query(int cr,int pre,int l,int r,int L,int R)
{
    if(l>=L&&r<=R) return sm[cr]-sm[pre];
    int mid=l+r>>1; bool fg=0;
    if(L<=mid) fg=query(ls[cr],ls[pre],l,mid,L,R);
    if(!fg&&mid<R) fg=query(rs[cr],rs[pre],mid+1,r,L,R);
    return fg;
}
void init()
{
    bin[0]=1;
    for(int i=1;i<=18;i++) bin[i]=bin[i-1]<<1;
}
int main()
{
    n=rdn(); m=rdn(); init();
    for(int i=1;i<=n;i++) a[i]=rdn(),mx=max(mx,a[i]);
    for(int i=1;i<=n;i++)
        build(rt[i],rt[i-1],1,mx,a[i]);
    for(int i=1,b,x,l,r;i<=m;i++)
    {
        b=rdn(); x=rdn(); l=rdn(); r=rdn();
        ans=0;  lj=0;
        for(int j=17;j>=0;j--)
        {
            if(b&bin[j]) {lo=lj; hi=lj+bin[j]-1;}
            else {lo=lj+bin[j]; hi=lj+bin[j+1]-1;}
            hi-=x; lo-=x;
            hi=min(hi,mx); lo=max(lo,0);

            if(lo<=hi&&query(rt[r],rt[l-1],1,mx,lo,hi))
                lj+=(b&bin[j]?0:bin[j]),ans+=bin[j];
            else lj+=(b&bin[j]?bin[j]:0);
        }
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Narh/p/9726446.html

时间: 2024-10-05 04:58:33

bzoj 4571 [Scoi2016]美味——主席树的相关文章

[BZOJ 4571][Scoi2016]美味(主席树)

Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 i 位顾客认为第 j 道菜的美味度为 bi XOR (aj+xi),XOR 表示异或 运算.第 i 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 li 道到第 ri 道中选择.请你帮助他们找出最美味的菜. Solution 按位贪心,每次通过查询一段区间是

BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]

传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边表开小了..... 好吧我$zz$了有根树加无向边干什么.... #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #de

BZOJ 3524: [Poi2014]Couriers( 主席树 )

卡我空间.... 这道题应该是主席树入门题...无修改 , 离散化都不用...出题人业界良心啊 一开始的空白树我 build 出来结果就多了整整 2n 个 Node , 然后就 MLE 了... ( 双倍经验 , 另一道见上图 ) ---------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring&g

【BZOJ 2809】dispatching(主席树)

这道题用主席树做做感觉非常舒服~~~ 首先题意来看,是说需要在树形结构中找到一个点i,并且找到这个点子树中的一些点组成一个集合,使得集合中的c之和不超过M,且Li*集合中元素个数和最大 简单地想想首先需要枚举每一个点,然后在子树中找到最小的k个点,使得sigma(C[i])(i = 1..k)不超过M,那么L[i]*k就是对于这个点来说的最优解 那么我们应该想到可以利用主席树中的性质,首先将树形结构通过dfs序转化到线性结构上,然后可以通过对子树中的记录信息进行判断从而得到答案(详见代码) 再想

BZOJ 1901 Dynamic Rankings 主席树

题目大意:可修改的区间第k小 这个主席树卡了我两天...切掉Count On A Tree 之后我就一直认为带修改的主席树是树状数组套可持久化线段树...其实我被误导了... 尼玛带修改的主席树和可持久化线段树毛关系都木有啊!!! 那就是动态的权值线段树啊啊啊啊啊啊啊!!! 好吧这里给不明白主席树的孩纸一些简介: 1.外层树状数组 2.里层线段树 3.线段树动态开节点.仅此而已.和可持久化完全没关系. 4.一个点上的线段树和其他版本毛关系都没有. 5.正常按照普通的树套树往里插就行了. 7.询问

bzoj 3772 精神污染 主席树+dfs序

精神污染 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 637  Solved: 177[Submit][Status][Discuss] Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是集经济和文化于一体的一大地区,是日本西部门户,海陆空交通设施发达.濑户内海沿岸气候温暖,多晴天,有日本少见的贸易良港神户港所在的神户市和曾是豪

bzoj 3524 [POI2014]KUR-Couriers (主席树)

题目大意:给你一个序列,求某个区间出现次数大于一半的数是什么 主席树裸题,刷刷水题提升自信= = 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define ll long long 5 #define il inline 6 #define N 500100 7 using namespace std; 8 //re 9 int n,m,tot; 10 int a[N],root[

bzoj4571/luogu3293 美味 (主席树+贪心)

首先想到建出可持久化trie树然后在上面贪心,但是它加了一个数所以不能这么做 但依然可以贪心,仿照上面那个的过程,如果设y是在第i位上^b是1的数(前面的位数已经贪好了),我只要在[l,r]范围内能有[y-x,y+(1<<i)-x-1)]的数,那这位异或出来就是可以是1的 1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 usin

[BZOJ4571][Scoi2016]美味 贪心+主席树

4571: [Scoi2016]美味 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 751  Solved: 410[Submit][Status][Discuss] Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 i 位顾客认为第 j 道菜的美味度为 bi XOR (aj+xi),XOR 表示异