zoukankan      html  css  js  c++  java
  • codeforces706D

    题意:给你一个可重集,有添加一个数,删除一个数,和询问一个数与这个集合中的一个元素的异或值最大是多少。所有数小于10^9。操作数小于20万。

    题解:

    我是按位处理,如果从高到低第i位为0,就去集合中找该位为一的,反之则找为0的,而这些数是连续的。

    标答线段树,因为它每一层分下去的节点是固定的。

    我没有考虑到这一点,写了个二分+树状数组。

    标程(by wuvin)

     1 #include<bits/stdc++.h>
     2 #define N 200005
     3 using namespace std;
     4 inline int read(){
     5        int ret=0;char ch=getchar();
     6        while(ch<'0'||ch>'9')ch=getchar();
     7        while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
     8        return ret;
     9 }
    10 struct xds{
    11     int son[2];
    12     int sz;
    13 }a[N*33];int cnt;
    14 const int L=0,R=1;
    15 void insert(int &k,int p,unsigned int x,int f){
    16     a[++cnt]=a[k];k=cnt;a[k].sz+=f;
    17     if(p==0) return;
    18     insert(a[k].son[x&(1<<(p-1)) ? 1:0],p-1,x,f);
    19 }
    20 int maxn=0;
    21 void query(int k,int p,unsigned x){
    22     if(p==0||k==0) return;int t=x&(1<<(p-1))? 0:1;
    23     if( a[a[k].son[t]].sz>0 ) maxn^=1<<(p-1),query(a[k].son[t],p-1,x);
    24     else query(a[k].son[t^1],p-1,x);
    25 }
    26 int n,rt;
    27 int main(){
    28     n=read();insert(rt,31,0,1);
    29     for(int i=1;i<=n;i++){
    30         char c=getchar();while(c!='+'&&c!='-'&&c!='?')c=getchar();
    31         if(c=='+') insert(rt,31,read(),1);
    32         else if(c=='-') insert(rt,31,read(),-1);
    33         else {
    34             maxn=0;query(rt,31,read());
    35             printf("%d
    ",maxn);
    36         }
    37     }
    38     return 0;
    39 }
    View Code

    我的

     1 #include<bits/stdc++.h>
     2 #define maxn 200005
     3 using namespace std;
     4 int n,m,mid,mac[maxn],ys1[maxn];
     5 int x[maxn],vnt[maxn],tot;
     6 long long full[35],mi[36],q;
     7 struct sd{
     8     int a,b;
     9     bool operator < (sd const &e) const{
    10     return a<e.a;};
    11 }does[maxn];
    12 char h;
    13 inline void add(int r,int pos){if(pos<=0) return;for(int i=pos;i<=tot;i+=(-i)&i) vnt[i]+=r;}
    14 int query(int pos){
    15     int h=0;
    16     for(int i=pos;i>0;i-=i&(-i)) h+=vnt[i];
    17     return h+1;
    18 }
    19 int find(long long k){
    20     int l=0,r=tot,mid;if(ys1[tot]<k) return tot;
    21     while(l<r){
    22         mid=l+r>>1;
    23         if(ys1[mid]==k) return mid;
    24         if(ys1[mid]<k) l=mid+1;
    25         else r=mid;
    26     }
    27     return l;
    28 }
    29 int main(){
    30     mi[0]=1;mi[1]=2;
    31     for(int i=2;i<=34;i++)mi[i]=mi[i-1]*2;
    32     for(int i=1;i<=34;i++){
    33         full[i]=mi[i]-1;
    34     }
    35     scanf("%d",&n);
    36     for(int i=1;i<=n;i++){
    37         getchar();
    38         h=getchar();
    39         switch(h)
    40         {
    41             case '+':
    42             mac[i]=1;
    43             break;
    44             case '-':
    45             mac[i]=2;
    46             break;
    47             case '?':
    48             mac[i]=3;
    49         }
    50         scanf("%d",&does[i].a);does[i].b=i;
    51     }
    52     sort(does+1,does+n+1);int pre=0,po1,po2;
    53     for(int i=1;i<=n;i++){
    54         if(does[i].a!=pre) tot++;
    55         ys1[tot]=does[i].a;pre=does[i].a;x[does[i].b]=tot;
    56     }vnt[0]=1;
    57     for(int i=1;i<=n;i++){
    58         if(mac[i]==1) add(1,x[i]);
    59         if(mac[i]==2) add(-1,x[i]);
    60         if(mac[i]==3){
    61             long long k=0,num;
    62             for(int j=32;j>=0;j--){
    63                 q=k|mi[j];q--;q|=mi[j];
    64                 if(query(find(q))==1) break;
    65                 int s=ys1[x[i]]&mi[j];
    66                 if(s>0) {
    67                     q=k|mi[j];q--;
    68                 }
    69                 else{
    70                     k|=mi[j];q=k-1;q|=mi[j];
    71                 }
    72                 po1=find(q);if(ys1[po1]>q)po1--;
    73                 po2=find(k-1);if(ys1[po2]>k-1) po2--;
    74                 num=query(po1)-query(po2);
    75                 if(num<=0){
    76                     if(s) {
    77                         if(k==0) break;
    78                         k=q+1;
    79                     }
    80                     else k=k&(full[34]^full[j+1]);
    81                 }
    82             }
    83             printf("%I64d
    ",k^ys1[x[i]]);
    84         }
    85     }
    86     return 0;
    87 }
    View Code

     

  • 相关阅读:
    linux sysfs (2)
    微软——助您启动云的力量网络虚拟盛会
    Windows Azure入门教学系列 全面更新啦!
    与Advanced Telemetry创始人兼 CTO, Tom Naylor的访谈
    Windows Azure AppFabric概述
    Windows Azure Extra Small Instances Public Beta版本发布
    DataMarket 一月内容更新
    和Steve, Wade 一起学习如何使用Windows Azure Startup Tasks
    现实世界的Windows Azure:与eCraft的 Nicklas Andersson(CTO),Peter Löfgren(项目经理)以及Jörgen Westerling(CCO)的访谈
    正确使用Windows Azure 中的VM Role
  • 原文地址:https://www.cnblogs.com/awipppp/p/5992461.html
Copyright © 2011-2022 走看看