bzoj 3600 没有人的算术

 

 

50分的做法:  

 

50分的程序:  

 1 #include<bits/stdc++.h>
 2 using namespace std;  
 3 #define lc  (x<<1)
 4 #define rc  (x<<1|1) 
 5 #define mid (l+r>>1)
 6 int const N=100000+10; 
 7 int const M=500000+10;  
 8 map<pair<int,int>,int >  mat;  
 9 int n,m,sum,a[N],b[N],id[N],x[N],y[N];  
10 int s[5001][5001],t[N<<2];  
11 int check(int t1,int t2){
12     if(t2==0 &&  t1)  return 1;  
13     if(t1==0 &&  t2)   return -1;  
14     int t=s[x[t1]][x[t2]];      
15     if(t) return t;  
16     return s[y[t1]][y[t2]];  
17 }
18 void pushup(int x){
19     int lch=id[t[lc]];  
20     int rch=id[t[rc]];  
21     if(check(lch,rch)>=0) 
22         t[x]=t[lc];  
23     else t[x]=t[rc];    
24 }
25 void build(int x,int l,int r){
26     if(l==r) {
27         t[x]=l;
28         return;  
29     }
30     build(lc,l,mid); 
31     build(rc,mid+1,r);  
32     pushup(x);  
33 }
34 void update(int x,int l,int r,int p){
35     if(l==r) return;   
36     if(p<=mid) update(lc,l,mid,p); 
37     else update(rc,mid+1,r,p);  
38     pushup(x);  
39 }
40 int query(int x,int l,int r,int ll,int rr){
41     if(ll<=l && r<=rr)  return t[x];  
42     int v1=0,v2=0;  
43     if(ll<=mid) v1=query(lc,l,mid,ll,rr); 
44     if(rr>mid)  v2=query(rc,mid+1,r,ll,rr);  
45     int lch=id[v1];  
46     int rch=id[v2];  
47     if(check(lch,rch)>=0) return v1; 
48     else return v2;  
49 }
50 int main(){
51     scanf("%d%d",&n,&m);
52     sum=1;  
53     s[1][0]=1;  
54     s[0][1]=-1;  
55     x[1]=y[1]=0; 
56     mat[make_pair(0,0)]=1;     
57     for(int i=1;i<=n;i++)  
58         a[i]=b[i]=0,id[i]=1;  
59     build(1,1,n);     
60     while (m--){
61         char st[2];  
62         int l,r,k;   
63         scanf("%s",st); 
64         scanf("%d%d",&l,&r);  
65         if(st[0]=='C'){
66             scanf("%d",&k);
67             int d=id[l];  
68             int t=id[r]; 
69             a[k]=d;  
70             b[k]=t;  
71             if(mat[make_pair(d,t)]==0) {
72                 mat[make_pair(d,t)]=++sum;  
73                 x[sum]=d; y[sum]=t; 
74                 for(int i=0;i<sum;i++){
75                     s[sum][i]=check(sum,i);  
76                     s[i][sum]=check(i,sum); 
77                 }
78             } 
79             id[k]=mat[make_pair(d,t)];  
80             update(1,1,n,k);  
81         }else {
82             printf("%d\n",query(1,1,n,l,r));  
83         }
84     } 
85     return 0;  
86 }
87 /* 
88 5 10  
89 C 1 1 1 
90 C 2 1 2 
91 Q 1 2 
92 C 4 4 4 
93 C 5 5 5 
94 Q 4 5 
95 Q 3 3 
96 C 4 2 3 
97 C 4 4 4 
98 Q 3 4 
99 */ 
View Code

 

70分的思想: 可以让平衡树来维护名次,这样就可以在$logn$的时间内比较两个数的大小 。 

总的时间复杂度就是$O(m*logn*logn)$了,由于n和m比较大,只能拿70分。  

 

 

100分的思想: 

这个做法非常好的,值得借鉴。 

我的满分程序:  

  1 #include<bits/stdc++.h>
  2 using namespace std;  
  3 #define LL long long 
  4 #define mid (l+r>>1) 
  5 #define lc  (x<<1)  
  6 #define rc  (x<<1|1)  
  7 int const N=100000+10;  
  8 int const M=1000000+10;  
  9 LL  const inf=(1LL<<62)-1;   
 10 int n,m,rt,sum,id[M];  
 11 LL v[M];  
 12 struct node{
 13     int l,r,w;    
 14     friend bool operator  < (node x,node y){
 15         return v[x.l]<v[y.l] || v[x.l]==v[y.l] &&  v[x.r]<v[y.r]; 
 16     }  
 17     friend bool operator ==(node x,node y){
 18         return v[x.l]==v[y.l] && v[x.r]==v[y.r];  
 19     } 
 20 }a[M],st[M<<2],t[M];   
 21     
 22 struct sctree{
 23     int ls[M],rs[M],sz[M],R,top,s[M];    
 24     int build(int l,int r,LL ll,LL rr){
 25         if(l>r) return 0;  
 26         int root=s[mid];  
 27         v[root]=(ll+rr)/2;  
 28         ls[root]=build(l,mid-1,ll,(ll+rr)/2-1);  
 29         rs[root]=build(mid+1,r,(ll+rr)/2+1,rr);  
 30         sz[root]=sz[ls[root]]+sz[rs[root]]+1; 
 31         return root;  
 32     }  
 33     void dfs(int x){
 34         if(!x) return;  
 35         dfs(ls[x]);  
 36         s[++top]=x;  
 37         dfs(rs[x]);  
 38     }  
 39     void  rebuild(int &x,LL l,LL r){ 
 40         top=0;  
 41         dfs(x);  
 42         x=build(1,top,l,r);  
 43     } 
 44     int  insert(int &x,LL l,LL r,node p){
 45         if(!x){
 46             x=++sum;v[x]=mid; sz[x]=1; t[x]=p; return x;  
 47         } 
 48         if(t[x]==p)  return x;   
 49         int ret; 
 50         if(p<t[x]) ret=insert(ls[x],l,mid,p); 
 51         else ret=insert(rs[x],mid+1,r,p);  
 52         sz[x]=sz[ls[x]]+sz[rs[x]]+1;  
 53         if(max(sz[ls[x]],sz[rs[x]])>0.75* sz[x])
 54             rebuild(x,l,r);  
 55         return ret;    
 56     }
 57     void db(int x){
 58         if(!x) return; 
 59         db(ls[x]);  
 60         cout<<x<<" "<<v[x]<<" "<<t[x].l<<" "<<t[x].r<<endl;  
 61         db(rs[x]);  
 62     }  
 63 }sc;  
 64 void modify(int x,int l,int r,int p,node v){
 65     if(l==r){
 66         st[x]=v; st[x].w=l; return;  
 67     }  
 68     if(p<=mid) modify(lc,l,mid,p,v);  
 69     else modify(rc,mid+1,r,p,v);  
 70     node t1=st[lc];  
 71     node t2=st[rc];  
 72     if(t1<t2) st[x]=t2; 
 73     else st[x]=t1;  
 74 }  
 75 node query(int x,int l,int r,int ll,int rr){
 76     if(l==ll && r==rr) return st[x];  
 77     if(rr<=mid) return query(lc,l,mid,ll,rr); 
 78     else if(ll>mid) return query(rc,mid+1,r,ll,rr);  
 79     else {
 80         node t1=query(lc,l,mid,ll,mid); 
 81         node t2=query(rc,mid+1,r,mid+1,rr); 
 82         if(t1<t2) return t2;  
 83         else return t1;  
 84     } 
 85 }   
 86 int main(){
 87     scanf("%d%d",&n,&m);   
 88     sc.insert(rt,1,inf,node{0,0,0});   
 89     for(int i=1;i<=n;i++)  
 90         id[i]=1;  
 91     for(int i=1;i<=n;i++)  
 92         modify(1,1,n,i,node{0,0,i});  
 93     while (m--){
 94         char cmd[3]; 
 95         int l,r,k; 
 96         scanf("%s%d%d",cmd,&l,&r);   
 97         if(cmd[0]=='C'){
 98             scanf("%d",&k);  
 99             a[k].l=id[l];  
100             a[k].r=id[r];  
101             id[k]=sc.insert(rt,1,inf,node{id[l],id[r],0});  
102             modify(1,1,n,k,a[k]);  
103         }else printf("%d\n",query(1,1,n,l,r).w);  
104     } 
105     return 0; 
106 }  
107 /* 
108 5 10 
109 C 1 1 1 
110 C 2 1 2 
111 Q 1 2  
112 C 4 4 4 
113 C 5 5 5 
114 Q 4 5 
115 Q 3 3 
116 C 4 2 3 
117 C 4 4 4
118 Q 3 4 
119 */  
View Code

 

posted @ 2019-07-05 16:14  zjxxcn  阅读(185)  评论(0编辑  收藏  举报