bzoj3217 ALOEXT

替罪羊套$01Trie$

一看就是傻逼树套树,后来一直$MLE$,发现有内存没删干净。删了之后$TLE$,$Trie$重载$new$和$delete$了就快的飞起了。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<vector>
  4 #define N 200050
  5 #define alp 0.75
  6 #define inf 0x7fffffff
  7 #define MAX(a,b) ((a>b)?(a):(b))
  8 #define MIN(a,b) ((a<b)?(a):(b))
  9 using namespace std;
 10 
 11 char xch,xB[1<<15],*xS=xB,*xTT=xB;
 12 #define getc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)
 13 inline int read()
 14 {
 15     int x=0,f=1;char ch=getc();
 16     while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getc();}
 17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
 18     return x*f;
 19 }
 20 
 21 int n,m,tot;
 22 namespace Trie{
 23     struct Node{
 24         Node *ch[2];
 25         int size;
 26         Node();
 27         inline void* operator new(size_t);
 28         inline void operator delete(void* p);
 29     }*null=new Node(),*root[N],*L[N],*C,*mempool;
 30     inline Node:: Node(){
 31         ch[0]=ch[1]=null;
 32         size=0;
 33     }
 34     std::vector<Node*>bin;
 35     inline void* Node::operator new(size_t){
 36         Node *p;
 37         if(!bin.empty()) {
 38             p = bin.back();
 39             bin.pop_back();
 40         }
 41         else {
 42             if(C == mempool) C = new Node[1 << 15], mempool = C + (1 << 15);
 43             p = C ++;
 44         }
 45         return p;
 46     }
 47     inline void Node::operator delete (void* p){
 48         bin.push_back((Node*)p);
 49     }
 50     inline void init(){
 51         null->ch[0]=null->ch[1]=null;null->size=0;
 52         for(int i=1;i<=n+m;i++)root[i]=new Node();
 53     }
 54     inline void dfs(Node *&rt){
 55         if(rt==null)return ;
 56         dfs(rt->ch[0]);
 57         dfs(rt->ch[1]);
 58         delete (rt);
 59     }
 60     inline void insert(Node *rt,int x){
 61         rt->size++;
 62         for(int i=19;~i;i--){
 63             bool t=(x>>i)&1;
 64             if(rt->ch[t]==null)
 65                 rt->ch[t]=new Node();
 66             rt=rt->ch[t];
 67             rt->size++;
 68         }
 69     }
 70     inline void del(Node *rt,int x){
 71         rt->size--;
 72         for(int i=19;~i;i--){
 73             bool t=(x>>i)&1;
 74             rt->ch[t]->size--;
 75             if(rt->ch[t]->size==0){/*dfs(rt->ch[t]);*/rt->ch[t]=null;break;}
 76             rt=rt->ch[t];
 77         }
 78     }
 79 }
 80 struct Node{
 81     Node *ch[2];
 82     int key,size,cover,ex,id,mx,sec;
 83     inline void pushup(){
 84         if(ex){
 85             mx=MAX(MAX(ch[0]->mx,ch[1]->mx),key);
 86             if(mx==key)sec=MAX(ch[0]->mx,ch[1]->mx);
 87             else if(mx==ch[0]->mx)sec=MAX(key,MAX(ch[0]->sec,ch[1]->mx));
 88             else sec=MAX(key,MAX(ch[0]->mx,ch[1]->sec));
 89         }
 90         else{
 91             mx=MAX(ch[0]->mx,ch[1]->mx);
 92             if(mx==ch[0]->mx)sec=MAX(ch[0]->sec,ch[1]->mx);
 93             else sec=MAX(ch[0]->mx,ch[1]->sec);
 94         }
 95         size=ch[0]->size+ch[1]->size+ex;
 96         cover=ch[0]->cover+ch[1]->cover+1;
 97     }
 98     inline bool bad(){
 99         return ch[0]->cover>=cover*alp+5||ch[1]->cover>=cover*alp+5;
100     }
101     Node(int x,int y);
102 }*null=new Node(0,0),*root,*sta[N];
103 int len,l_len;
104 inline Node :: Node(int x,int y){
105     key=mx=x;sec=-inf;id=y;
106     ch[0]=ch[1]=null;
107     size=cover=ex=1;
108 }
109 inline void init(){
110     null->ch[0]=null->ch[1]=null;
111     null->size=null->cover=null->ex=0;
112     null->mx=null->sec=-inf;
113     root=null;
114 }
115 inline Node **insert(Node *&now,int x,int y,int pos){
116     if(now==null){
117         now=new Node(y,pos);
118         Trie::insert(Trie::root[now->id],y);
119         return &null;
120     }
121     Trie::insert(Trie::root[now->id],y);
122     Node **ret;
123     if(now->ch[0]->size>=x)ret=insert(now->ch[0],x,y,pos);
124     else ret=insert(now->ch[1],x-now->ch[0]->size-now->ex,y,pos);
125     now->pushup();
126     if(now->bad())ret=&now;
127     return ret;
128 }
129 
130 inline void travel(Node *now){
131     if(now==null)return;
132     Trie::dfs(Trie::root[now->id]);
133     travel(now->ch[0]);
134     if(now->ex){sta[++len]=now;travel(now->ch[1]);}
135     else{travel(now->ch[1]);delete(now);}
136 }
137 inline Node *divide(int l,int r){
138     if(l>r)return null;
139     int mid=(l+r)>>1;
140     sta[mid]->ch[0]=divide(l,mid-1);
141     sta[mid]->ch[1]=divide(mid+1,r);
142     sta[mid]->pushup();
143     Trie::root[sta[mid]->id]=new Trie::Node();
144     for(int i=l;i<=r;i++)
145         Trie::insert(Trie::root[sta[mid]->id],sta[i]->key);
146     return sta[mid];
147 }
148 inline void rebuild(Node *&now){
149     len=0;travel(now);
150     now=divide(1,len);
151 }
152 inline void insert(int x,int y,int pos){
153     Node **p=insert(root,x,y,pos);
154     if(*p!=null)rebuild(*p);
155 }
156 inline int find(Node *now,int x){
157     if(now->ex&&x==now->ch[0]->size+1)return now->key;
158     if(now->ch[0]->size>=x)return find(now->ch[0],x);
159     else return find(now->ch[1],x-now->ch[0]->size-now->ex);
160 }
161 inline void del(Node *now,int x,int y){
162     Trie::del(Trie::root[now->id],y);
163     if(now->ex&&x==now->ch[0]->size+1){now->ex=0;now->pushup();return;}
164     if(now->ch[0]->size>=x)del(now->ch[0],x,y);
165     else del(now->ch[1],x-now->ch[0]->size-now->ex,y);
166     now->pushup();
167 }
168 inline void del(int x){
169     del(root,x,find(root,x));
170     if(root->size<=root->cover*alp+5)rebuild(root);
171 }
172 inline void change(Node *now,int x,int y,int z){
173     Trie::del(Trie::root[now->id],y);
174     Trie::insert(Trie::root[now->id],z);
175     if(now->ex&&x==now->ch[0]->size+1){
176         now->key=z;
177         now->pushup();
178         return;
179     }
180     if(now->ch[0]->size>=x)change(now->ch[0],x,y,z);
181     else change(now->ch[1],x-now->ch[0]->size-now->ex,y,z);
182     now->pushup();
183 }
184 inline void change(int x,int y){
185     change(root,x,find(root,x),y);
186 }
187 int MX,SEC;
188 inline void query_init(Node *now,int l,int r){
189     if(now==null)return;
190     if(r-l+1==now->size){
191         if(now->mx>MX){SEC=MAX(MX,now->sec);MX=now->mx;}
192         else SEC=MAX(SEC,now->mx);
193         Trie::L[++l_len]=Trie::root[now->id];
194         return;
195     }
196     if(now->ex&&now->ch[0]->size+1>=l&&now->ch[0]->size+1<=r){
197         Trie::insert(Trie::L[1],now->key);
198         if(now->key>MX)SEC=MX,MX=now->key;
199         else SEC=MAX(SEC,now->key);
200     }
201     if(now->ch[0]->size>=l)query_init(now->ch[0],l,MIN(now->ch[0]->size,r));
202     if(now->ch[0]->size+now->ex<r)query_init(now->ch[1],MAX(1,l-now->ch[0]->size-now->ex),r-now->ch[0]->size-now->ex);
203 }
204 inline int query_work(int x){
205     int ans=0;
206     for(int i=19;~i;i--){
207         int t=(x>>i)&1,num=0;
208         for(int j=1;j<=l_len;j++)
209             num+=Trie::L[j]->ch[t^1]->size;
210         ans+=(num?1:0)<<i;
211         for(int j=1;j<=l_len;j++)
212             Trie::L[j]=Trie::L[j]->ch[t^(num?1:0)];
213     }
214     return ans;
215 }
216 inline int query(int l,int r){
217     l_len=0;
218     Trie::L[++l_len]=new Trie::Node();
219     MX=SEC=-inf;
220     query_init(root,l,r);
221     Trie::L[0]=Trie::L[1];
222     int ans=query_work(SEC);
223     Trie:: dfs(Trie::L[0]);
224     return ans;
225 }
226 int main(){
227     n=read();m=read();tot=n;
228     init();Trie::init();
229     for(int i=1,x;i<=n;i++){
230         x=read();
231         sta[i]=new Node(x,i);
232     }
233     root=divide(1,n);
234     int ans=0,x,y,l,r;char ch;
235     while(m--){
236         ch=getc();
237         while(ch!='I'&&ch!='D'&&ch!='C'&&ch!='F')ch=getc();
238         if(ch=='I'){
239             x=(read()+ans)%n;y=(read()+ans)%1048576;
240             insert(x,y,++tot);n++;
241         }
242         if(ch=='D'){
243             x=(read()+ans)%n;
244             del(x+1);n--;
245         }
246         if(ch=='C'){
247             x=(read()+ans)%n;y=(read()+ans)%1048576;
248             change(x+1,y);
249         }
250         if(ch=='F'){
251             l=(read()+ans)%n;r=(read()+ans)%n;
252             ans=query(l+1,r+1);
253             printf("%d\n",ans);
254         }
255     }
256     return 0;
257 }
View Code

 

posted @ 2018-01-15 13:20  Ren_Ivan  阅读(265)  评论(0编辑  收藏  举报