zoukankan      html  css  js  c++  java
  • LOJ517「LibreOJ β Round #2」计算几何瞎暴力

    LOJ517「LibreOJ β Round #2」计算几何瞎暴力

    要求维护一个全局异或,动态在末尾加元素,询问区间和,全局排序的数据结构。

    首先因为是全局异或,这个可以想到直接打标记,然后在末尾加元素可以用一个缓存数组,重点在于全局排序还要区间询问和该怎么办。

    根据排序,可以想到 (Trie) 来做,同时区间和其实就是对应 (Trie) 树上的一段,再加之全局异或标记,其实就是树上 0/1 路径的交换。

    所以对于已经排好序的存到 (Trie) 里,剩下的搞一个数组缓存并随时维护前缀和即可。

    然后区间和就是相当于在 (Trie) 里询问再加上一段前缀和,可以用类似 (Trie) 树上二分的操作来实现。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=1e6+5;
    int a[N],pos,n,m;
    int pre[N][31],ls[N<<1],rs[N<<1],bit[N<<1][31],siz[N<<1],num[N<<1],cnt=1,x,tmpx,dx;
    void ins(int k){
        ++siz[1];
        for(int j=0,p=1;j<=30;j++,p<<=1) bit[1][j]+=((k&p)>0);
        for(int i=30,t=1<<30,id=1;i>=0;i--,t>>=1){
            if(k&t){
                if(!rs[id]) rs[id]=++cnt,num[cnt]=num[id]+t;
                id=rs[id];
            }
            else{
                if(!ls[id]) ls[id]=++cnt,num[cnt]=num[id];
                id=ls[id];
            }
            for(int j=0,p=1;j<=30;j++,p<<=1) bit[id][j]+=((k&p)>0);
            ++siz[id];
        }
        return ;
    }
    long long GetNum(int t,int k,int id){
        if(!k||!id) return 0; 
        if(k==siz[id]){
            long long res=0;
            for(int j=0,p=1;j<=30;j++,p<<=1) res+=1ll*p*((p&x)?(k-bit[id][j]):bit[id][j]);
            return res; 
        }
        if(t==0){return 1ll*k*(num[id]^x);}
        if(dx&t)if(k<=siz[rs[id]]) return GetNum(t>>1,k,rs[id]); else return GetNum(t>>1,siz[rs[id]],rs[id])+GetNum(t>>1,k-siz[rs[id]],ls[id]); 
        else if(k<=siz[ls[id]]) return GetNum(t>>1,k,ls[id]); else return GetNum(t>>1,siz[ls[id]],ls[id])+GetNum(t>>1,k-siz[ls[id]],rs[id]);
    }
    signed main(){
    	
        read(n);
        for(int i=1;i<=n;i++){
            read(a[i]);
            for(int j=0,p=1;j<=30;j++,p<<=1) pre[i][j]=pre[i-1][j]+((a[i]&p)>0);
        }
        read(m);int op,k;
        while(m--){
            read(op);
            if(op==1){
            	read(k);
                a[++n]=k^x;
                for(int j=0,p=1;j<=30;j++,p<<=1) pre[n][j]=pre[n-1][j]+((a[n]&p)>0);
            }
            else if(op==3){
                int g;read(g);
                x^=g,tmpx^=g;
            }
            else if(op==4){
                while(pos<n) ins(a[++pos]);
                dx^=tmpx,tmpx=0;
            }
            else{
                int l,r;read(l),read(r);
    			long long res;
                if(r<=pos){
                    res=GetNum(1<<30,r,1)-GetNum(1<<30,l-1,1);
                    write(res),putchar('
    ');
                }
                else if(l>pos){
                    res=0;
                    for(int j=0,p=1;j<=30;j++,p<<=1) res+=1ll*p*((p&x)?(r-l+1-pre[r][j]+pre[l-1][j]):(pre[r][j]-pre[l-1][j]));
                    write(res),putchar('
    ');
                }
                else{
                    res=GetNum(1<<30,pos,1)-GetNum(1<<30,l-1,1);
                    for(int j=0,p=1;j<=30;j++,p<<=1) res+=1ll*p*((p&x)?(r-pos-pre[r][j]+pre[pos][j]):(pre[r][j]-pre[pos][j]));
                    write(res),putchar('
    ');
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    T2487 公交司机(搜索题)(小L的一生)
    T2485 汉诺塔升级版(普及)(递归)
    T2483 电梯(模拟题)
    将图片返回到前端
    session
    TCP协议
    socket
    断点调试
    解析字符串
    Cookie
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14667407.html
Copyright © 2011-2022 走看看