zoukankan      html  css  js  c++  java
  • 【LOJ】#2016. 「SCOI2016」美味

    题解

    做了一下SCOI2015,于是决定搬运SCOI2016= v =

    如果没有加法,我们可以向左向右节点查找
    每个总权值是2^18 - 1,然后左右分,那么每次是一个完整的节点
    如果有了加法,那么我们如果希望有数满足某一位是1或者0,是一段取值的区间,我们要保证这个区间的左右端点减少x后这个区间里还有值
    我们可以通过一次(log n)的操作完成这个东西
    那么我们二分的话,复杂度也是(log n)
    所以总复杂度就是(O(m log^2 n))

    代码

    #include <bits/stdc++.h>
    //#define ivorysi
    #define MAXN 200005
    typedef long long int64;
    typedef unsigned int u32;
    using namespace std;
    const int MOD = 1000000007;
    int n,m;
    int a[MAXN];
    struct node {
        int lc,rc;
        int size;
    }tr[MAXN * 20];
    int rt[MAXN],nodecnt;
    int MAXVAL = 100000;
    void add(const int &x,int &y,int l,int r,int pos) {
        y = ++nodecnt;
        tr[y] = tr[x];
        tr[y].size++;
        if(l == r)return;
        int mid = (l + r) >> 1;
        if(pos <= mid) add(tr[x].lc,tr[y].lc,l,mid,pos);
        else add(tr[x].rc,tr[y].rc,mid + 1,r,pos);
    }
    int query(const int &u,int l,int r,int ql,int qr) {
        if(l == ql && r == qr) return tr[u].size;
        int mid = (l + r) >> 1;
        if(qr <= mid) return query(tr[u].lc,l,mid,ql,qr);
        else if(ql > mid) return query(tr[u].rc,mid + 1,r,ql,qr);
        else {
    	return query(tr[u].lc,l,mid,ql,mid) + query(tr[u].rc,mid + 1,r,mid + 1,qr);
        }
    }
    void Init() {
        scanf("%d%d",&n,&m);
        for(int i = 1 ; i <= n ; ++i) {
    	scanf("%d",&a[i]);
    	add(rt[i - 1],rt[i],0,MAXVAL,a[i]);
        }
    }
    int getsize(int L,int R,int ql,int qr) {
        if(ql < 0) ql = 0;
        
        qr = min(qr,MAXVAL);
        if(qr < ql) return 0 ;
        return query(rt[R],0,MAXVAL,ql,qr) - query(rt[L - 1],0,MAXVAL,ql,qr);
    }
    int Binary(int b,int x,int Lrt,int Rrt) {
        int L = 0,R = (1 << 18) - 1;
        int NUM = 0;
        for(int i = 17 ; i >= 0 ; --i) {
    	if(b >> i & 1) {
    	    int T = NUM + (1 << i) - 1;
    	    if(getsize(Lrt,Rrt,L - x,T - x) > 0) {
    		R = T;    
    	    }
    	    else {
    		L = T + 1;
    		NUM += (1 << i);
    	    }
    	}
    	else {
    	    int T = NUM + (1 << i);
    	    if(getsize(Lrt,Rrt,T - x,R - x) > 0) {
    		NUM += (1 << i);
    		L = T;
    	    }
    	    else R = T - 1; 
    	}
        }
        return b ^ NUM;
    }
    void Solve() {
        Init();
        int b,x,l,r;
        while(m--) {
    	scanf("%d%d%d%d",&b,&x,&l,&r);
    	printf("%d
    ",Binary(b,x,l,r));
        }
    }
    
    int main() {
    #ifdef ivorysi
        freopen("food1.in","r",stdin);
    #endif
        Solve();
    }
    
  • 相关阅读:
    安装使用composer基本流程
    数据库关于group by 两个或以上条件的分析
    PHP中VC6、VC9、TS、NTS版本的区别与用法详解
    Linux 守护进程的启动方法
    PHP安装包TS和NTS的区别
    kubernetes 简单service的例子
    kubernetes 每个node上只能运行一个副本DaemonSet
    kubernetes 利用label标签来绑定到特定node运行pod
    kubernetes 简单yaml文件运行例子deployment
    kubernetes Helm-chart web UI添加
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9155808.html
Copyright © 2011-2022 走看看