zoukankan      html  css  js  c++  java
  • DTOJ #2656. 美味(food)

    【题目描述】

    一家餐厅有 $ n $ 道菜,编号 $ 1 ldots n $,大家对第 $ i $ 道菜的评价值为 $ a_i :( 1 leq i leq n ) :$。有 $ m $ 位顾客,第 $ i $ 位顾客的期望值为 $ b_i $,而他的偏好值为 $ x_i $。因此,第 $ i $ 位顾客认为第 $ j $ 道菜的美味度为 $ b_i mathbin{ ext{xor}} (a_j + x_i) $($ ext{xor} $ 表示异或运算)。
    第 $ i $ 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 $ l_i $ 道到第 $ r_i $ 道中选择。请你帮助他们找出最美味的菜。

    【输入格式】

    第一行,两个整数,$ n, m $,表示菜品数和顾客数。
    第二行,$ n $ 个整数,$ a_1, a_2, ldots, a_n $,表示每道菜的评价值。
    第三至 $ m + 2 $ 行,每行 $ 4 $ 个整数,$ b, x, l, r $,表示该位顾客的期望值,偏好值,和可以选择菜品区间。

    【输出格式】

     输出 $ m $ 行,每行一个整数表示该位顾客选择的最美味的菜的美味值。

    【样例】

    样例输入 

    4 4
    1 2 3 4
    1 4 1 4
    2 3 2 3
    3 2 3 3
    4 1 2 4

    样例输出
    9
    7
    6
    7

    【数据范围与提示】

    对于 $30\%$ 的数据,$ 1 le m le 10^3 $。
    对于 $100\%$ 的数据,$ 1 leq n leq 2 imes 10 ^ 5, 0 leq a_i, b_i, x_i < 10 ^ 5, 1 leq l_i leq r_i leq n(1 leq i leq m), 1 leq m leq 10 ^ 5 $。

    【题解】

     看到异或不难想到 $Trie$ 树,然而这题跟 $Trie$ 树没啥关系(如果你硬要把值域线段树和Trie说成同一个东西这句话当我没说)。

    要求的式子显然没法直接算,根据一般套路,考虑按位贪心。

    记已经考虑完的位答案为 $ans$,考虑当前第 $i$ 位,如果 $b$ 的当前位为 $0$,显然如果 $a_j+x$ 这一位为 $1$ 更优。而 $a_j+x$ 的前几位一定要与 $ans$ 相同,则 $a_j+x$ 的取值范围为 $[ans+2^i,ans+2^{i+1}-1]$,可得 $a_j$ 的范围应在 $[ans+2^i-x,ans+2^{i+1}-1-x]$ 内最优。这是值域的限制。而 $l,r$ 是对位置的限制。二维限制其中一位满足可减性,用主席树维护即可。$b$ 的当前位为 $1$ 同理。

    【代码】

    #include<bits/stdc++.h>
    inline int read ( void )
    {
    	int x=0;char ch;bool f=true;
    	while ( !isdigit(ch=getchar()) ) if ( ch=='-' ) f=false;
    	for ( x=ch^48;isdigit(ch=getchar()); ) x=(x<<1)+(x<<3)+(ch^48);
    	return f ? x : -x ;
    }
    int L,R,n,A[200010],tot,root[200010];
    struct tree { int ls,rs,tot; } t[10000000];
    inline void modify ( int &k,int fr,int l,int r,int p )
    {
    	t[k=++tot].tot=t[fr].tot+1;
    	if ( l==r ) return;
    	int mid=(l+r)>>1;
    	if ( p<=mid ) modify(t[k].ls,t[fr].ls,l,mid,p),t[k].rs=t[fr].rs;
    	else modify(t[k].rs,t[fr].rs,mid+1,r,p),t[k].ls=t[fr].ls;
    }
    inline int query ( int k1,int k2,int l,int r,int ql,int qr )
    {
    	if ( ql>qr ) return 0;
    	if ( ql<=l and r<=qr ) return t[k1].tot-t[k2].tot;
    	int mid=(l+r)>>1,res=0;
    	if ( ql<=mid ) res+=query(t[k1].ls,t[k2].ls,l,mid,ql,qr);
    	if ( qr>mid ) res+=query(t[k1].rs,t[k2].rs,mid+1,r,ql,qr);
    	return res;
    }
    signed main()
    {
    	n=read();int q=read();
    	for ( int i=1;i<=n;i++ ) R=std::max(R,A[i]=read());
    	for ( int i=1;i<=n;i++ ) modify(root[i],root[i-1],L,R,A[i]);
    	while ( q-- )
    	{
    		int b=read(),x=read(),l=read(),r=read(),ans=0;
    		for ( int i=18;~i;i-- )
    			if ( b&(1<<i) )
    			{
    				if ( !query(root[r],root[l-1],L,R,std::max(ans-x,L),std::min(ans+(1<<i)-1-x,R)) ) ans+=(1<<i);
    			}
    			else
    			{
    				if ( query(root[r],root[l-1],L,R,std::max(ans+(1<<i)-x,L),std::min(ans+(1<<(i+1))-1-x,R)) ) ans+=(1<<i);
    			}
    		printf("%d
    ",ans^b);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/RenSheYu/p/11311574.html
Copyright © 2011-2022 走看看