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

    https://loj.ac/problem/517

    题解

    首先我们如果没有排序这个骚操作的话,可以直接记一下各个数位的前缀和,然后异或标记给全局打,查询的时候先把区间信息提取出来然后整体异或就好了。

    对于排序,我们考虑对所有排好序的节点建(trie)树,这样即使有全局异或标记,我们也可以在(trie)树上完成前缀信息的查询。

    然后就做完了。

    代码

    #include<bits/stdc++.h>
    #define N 200009
    #define ls ch[cnt][0]
    #define rs ch[cnt][1]
    using namespace std;
    typedef long long ll;
    const int maxn=30;
    int a[N],n,q;
    int ch[N*maxn][2],ct[N*maxn][maxn],size[N*maxn],sm[N][maxn];
    int tot,rot;
    int tag,nowtag;
    ll ton[32],nw;
    inline ll rd(){
    	ll x=0;char c=getchar();bool f=0;
    	while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f?-x:x;
    }
    void ins(int &cnt,int x,int p){
    	if(!cnt)cnt=++tot;
    	size[cnt]++;
    	for(int i=0;i<=29;++i)if((1<<i)&x)ct[cnt][i]++;
    	if(p<0)return;
    	int o=(x&(1<<p))!=0;
    	if(o)ins(rs,x,p-1);
    	else ins(ls,x,p-1);
    }
    inline ll getsum(int now){
    	memset(ton,0,sizeof(ton));
    	if(now>=nw){
    		for(int i=0;i<=29;++i)ton[i]+=sm[now][i];
    	}
    	else{
    		int cnt=rot,siz=now;
    		for(int i=29;i>=0;--i){
    			int lson=ls,rson=rs;
    			if(nowtag&(1<<i))swap(lson,rson);
    			if(size[lson]>=siz)cnt=lson;
    			else{
    				for(int j=0;j<=29;++j)ton[j]+=ct[lson][j];
    				siz-=size[lson];
    				cnt=rson;
    			}
    		}
    		if(siz){
    			for(int i=0;i<=29;++i)ton[i]+=(ct[cnt][i]!=0)*siz;
    		}
    	}
    	ll ans=0;
    	for(int i=0;i<=29;++i){
    		ll ss;
    		if(tag&(1<<i))ss=now-ton[i];else ss=ton[i];
    	//	cout<<ss<<" ";
    		ans+=ss*(1ll<<i);
    	}
    	//cout<<"??
    ";
    	return ans;
    }
    int main(){
    //	freopen("1.txt","r",stdin);
    //	freopen("out","w",stdout);
    	n=rd();
    	nw=1;
    	for(int i=1;i<=n;++i){
    	  a[i]=rd();
    	  for(int j=0;j<=29;++j)sm[i][j]=sm[i-1][j]+((a[i]&(1<<j))!=0);
        }
    	q=rd();
    	int opt,x,l,r;
    	while(q--){
    		opt=rd();
    		if(opt==1){
    			x=rd();x^=tag;
    			++n;a[n]=x;
    			for(int j=0;j<=29;++j)sm[n][j]=sm[n-1][j]+((a[n]&(1<<j))!=0);
    		}
    		else if(opt==2){
    			l=rd();r=rd();
    			printf("%lld
    ",getsum(r)-getsum(l-1));
    		}
    		else if(opt==3)tag^=rd();
    		else if(opt==4){
    			nowtag=tag;
    			while(nw<=n)ins(rot,a[nw],29),nw++;
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    SQL函数 【转】
    Oracle修改表,提示“资源正忙,要求指定NOWAIT”
    网关的通俗讲解【转】
    程序员小抄大全
    JQuery 中each的使用方法
    JQueryUI入门所有效果说明【转】
    随记小笔(20100820)
    asp.net操纵Oracle存储过程
    JQuery技巧总结【转】
    Centos7 进入单用户模式,修复系统
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/11093089.html
Copyright © 2011-2022 走看看