zoukankan      html  css  js  c++  java
  • [SCOI2016]美味

    链接:https://www.luogu.org/problemnew/show/3293

    题意:

    一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1<=i<=n)。有 m 位顾客,第 i 位顾客的期望值为 bi,而他的偏好值为 xi 。因此,第 i 位顾客认为第 j 道菜的美味度为 bi XOR (aj+xi),XOR 表示异或运算。

    第 i 位顾客希望从这些菜中挑出他认为最美味的菜,即美味值最大的菜,但由于价格等因素,他只能从第 li 道到第 ri 道中选择。请你帮助他们找出最美味的菜。

    数据范围:n,m,a[i]<=10e5

    题解:

    很水的一道题啊。。。

    考虑xor运算,每一位都是互相独立的,所以若要总的值越大,即越靠前的位越大

    从前向后考虑每一位,若该位要取1才能得到最大值

    则(aj+xi)的范围应该sum--------sum+(1<<i)-1 {这步最关键}

    则只需查找aj属于sum-a[j]-------sum+(1<<i)-1-a[j]即可

    之后就显然了。。主席树维护

    ****注意优先级要多打括号啊。。。

    代码:

    #include <bits/stdc++.h>
    #define mid (h+t)/2
    #define maxn 100000
    using namespace std;
    struct re{int h,t,x;}p[10000000];
    int n,m,j,now,a[300000],fa[300000],f[100];
    void build(int x,int h,int t)
    {
        now=max(now,x);
        if (h==t) return;
        p[x].h=x*2; p[x].t=x*2+1;
        build(x*2,h,mid); build(x*2+1,mid+1,t);
    };
    void insert(int x,int &y,int num,int h,int t)
    {  
         y=++now,p[y]=p[x]; p[y].x++;
         if (h==t) return;
         if (mid>=num) insert(p[x].h,p[y].h,num,h,mid);
         else insert(p[x].t,p[y].t,num,mid+1,t);
    };
    bool query(int x,int y,int h1,int t1,int h,int t)
    {
        if (t<h1 || t1<h) return(false); 
        if (h1<=h && t<=t1) return((p[y].x-p[x].x)>0);
        return(query(p[x].h,p[y].h,h1,t1,h,mid) || query(p[x].t,p[y].t,h1,t1,mid+1,t));    
    }
    int main(){
        freopen("noip.in","r",stdin);
        freopen("noip.out","w",stdout); 
        cin>>n>>m;
        build(1,1,n); 
        fa[0]=1;
        for (int i=1;i<=n;i++) 
          cin>>a[i],insert(fa[i-1],fa[i],a[i],0,maxn);
        for (j=1;f[j-1]<=100000;j++) f[j]=1<<(j-1);
      int tmp=j-1;
        for (int i=1;i<=m;i++)
        {
            int c1,d1,x,y,ll=0;
            cin>>c1>>d1>>x>>y;
            for (int j=tmp;j>0;j--)
            {
              if ((f[j]&c1)>0)
              {
                if (!query(fa[x-1],fa[y],max(0,ll-d1),ll+f[j]-1-d1,0,maxn))
                  ll+=f[j];
            }
            else 
              if (query(fa[x-1],fa[y],max(0,ll+f[j]-d1),ll+2*f[j]-1-d1,0,maxn))
                ll+=f[j];
            }
            cout<<(c1^ll)<<endl;
      }
    }
  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8025535.html
Copyright © 2011-2022 走看看