牛客 买礼物

题目链接:https://ac.nowcoder.com/acm/contest/9983/E

思路: 把问题转换成 求区间中的数的下一个与当前数相同的数的最小值,

即区间最小值如果 小于r的话 那么就证明当前区间至少有两个相同的数

用nxt[] 记录与当前数相同的下一个数的位置,last 为与当前数相同的上一个数的位置,然后线段树维护nxt 即可

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=1e6+10;
  4 const int mod=1e9+7;
  5 #define ll long long
  6 #define pi pair<int,int>
  7 #define fi first
  8 #define sc second
  9 #define pb push_back
 10 struct ac
 11 {
 12     int l,r,v;
 13 };
 14 ac tr[maxn*2];
 15 int a[maxn],pos[maxn];
 16 int nxt[maxn],last[maxn];
 17 
 18 void pushup(int x)
 19 {
 20     tr[x].v=min(tr[x<<1].v,tr[x<<1|1].v);
 21 }
 22 
 23 void build(int x,int l,int r)
 24 {
 25     tr[x]={l,r};
 26     if(l==r)
 27     {
 28         tr[x].v=nxt[l];
 29     }
 30     else
 31     {
 32         int mid=(l+r)/2;
 33         build(x<<1,l,mid);
 34         build(x<<1|1,mid+1,r);
 35         pushup(x);
 36     }
 37 }
 38 
 39 void update(int x,int p,int v)
 40 {
 41     int L=tr[x].l,R=tr[x].r;
 42     if(L==R)
 43     {
 44         tr[x].v=v;
 45     }
 46     else
 47     {
 48         int mid=(L+R)/2;
 49         if(p<=mid) update(x<<1,p,v);
 50         if(p>mid) update(x<<1|1,p,v);
 51         pushup(x);
 52     }
 53 }
 54 
 55 int query(int x,int l,int r)
 56 {
 57     int L=tr[x].l,R=tr[x].r;
 58     if(l<=L&&R<=r)
 59     {
 60         return tr[x].v;
 61     }
 62     else
 63     {
 64         int mid=(L+R)/2;
 65         int ans=1e9;
 66         if(l<=mid) ans=query(x<<1,l,r);
 67         if(r>mid) ans=min(ans,query(x<<1|1,l,r));
 68         return ans;
 69     }
 70 }
 71 
 72 
 73 
 74 int main()
 75 {
 76     ios::sync_with_stdio(0);
 77     cin.tie(0);
 78     int n,q;
 79     cin>>n>>q;
 80     for(int i=1;i<=n;i++) cin>>a[i];
 81     for(int i=1;i<=n;i++)
 82     {
 83         last[i]=pos[a[i]];
 84         pos[a[i]]=i;
 85     }
 86     for(int i=1;i<=n;i++) pos[a[i]]=n+1;
 87     for(int i=n;i>=1;i--)
 88     {
 89         nxt[i]=pos[a[i]];
 90         pos[a[i]]=i;
 91     }
 92     build(1,1,n);
 93     while(q--)
 94     {
 95         int d;
 96         cin>>d;
 97         if(d==1)
 98         {
 99             int x;
100             cin>>x;
101             nxt[last[x]]=nxt[x];
102             last[nxt[x]]=last[x];
103             update(1,last[x],nxt[x]);
104             nxt[x]=n+1;
105             update(1,x,n+1);
106         }
107         else
108         {
109             int l,r;
110             cin>>l>>r;
111             if(query(1,l,r)>r) cout<<0<<'\n';
112             else cout<<1<<'\n';
113         }
114     }
115 
116 
117 
118 
119 }
View Code

 

posted @ 2021-02-12 11:47  canwinfor  阅读(56)  评论(0)    收藏  举报