zoukankan      html  css  js  c++  java
  • cf1000F One Occurrence (线段树)

    这题我是离线做的

    设i位置的数上次出现的位置是pre[i](如果第一次出现那就是0)

    可以想到,用线段树维护一个区间的pre的最小值,如果它小于区间左端点,那这个数就是一个合法的答案

    但直接这样做是错的

    考虑1,2,3,4,[1,1],5,虽然前一个1的pre在区间外面,但他后面还有一个1啊

    所以可以按照询问的右端点排序,推着来维护这个最小值

    具体来说,对于i,先把i位置的值改成pre[i],然后如果有pre[i],那把pre[i]位置的值改成inf(一开始都要初始化成inf)

    然后再查的话,我查到的就都是这个区间里的最后一次出现的那个数了,就不会有锅

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=5e5+10;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 int N,Q,pre[maxn],A[maxn],tmp[maxn],ans[maxn];
    16 pa mn[maxn<<2];
    17 struct Node{
    18     int l,r,i;
    19 }que[maxn];
    20 
    21 inline bool cmp(Node a,Node b){return a.r<b.r;};
    22 
    23 inline void update(int p){
    24     mn[p]=min(mn[p<<1],mn[p<<1|1]);
    25 }
    26 
    27 void change(int p,int l,int r,int x,int y){
    28     if(l==r) mn[p]=make_pair(y,x);
    29     else{
    30         int m=l+r>>1;
    31         if(x<=m) change(p<<1,l,m,x,y);
    32         else change(p<<1|1,m+1,r,x,y);
    33         update(p);
    34     }
    35 }
    36 
    37 pa query(int p,int l,int r,int x,int y){
    38     if(x<=l&&r<=y) return mn[p];
    39     int m=l+r>>1;pa re=make_pair(N+1,0);
    40     if(x<=m) re=query(p<<1,l,m,x,y);
    41     if(y>=m+1) re=min(re,query(p<<1|1,m+1,r,x,y));
    42     return re;
    43 }
    44 
    45 int main(){
    46     int i,j,k;
    47     N=rd();
    48     for(i=1;i<=N;i++){
    49         A[i]=rd();
    50         pre[i]=tmp[A[i]],tmp[A[i]]=i;
    51     }Q=rd();
    52     for(i=1;i<=Q;i++){
    53         que[i].l=rd(),que[i].r=rd(),que[i].i=i;
    54     }sort(que+1,que+Q+1,cmp);
    55     CLR(mn,127);
    56     for(i=1,j=1;i<=Q;i++){
    57         for(;j<=que[i].r&&j<=N;j++){
    58             if(pre[j]) change(1,1,N,pre[j],N+1);
    59             change(1,1,N,j,pre[j]);
    60         }
    61         pa re=query(1,1,N,que[i].l,que[i].r);
    62         if(re.first<que[i].l) ans[que[i].i]=A[re.second];
    63     }
    64     for(i=1;i<=Q;i++) printf("%d
    ",ans[i]);
    65     return 0;
    66 }
  • 相关阅读:
    Vue学习笔记【28】——Vue路由(使用 children 属性实现路由嵌套)
    Vue学习笔记【27】——Vue路由(设置路由)
    Vue学习笔记【26】——Vue路由(什么是路由)
    Vue学习笔记【25】——Vue组件(组件间传值)
    Vue学习笔记【24】——Vue组件(组件切换)
    Vue学习笔记【23】——Vue组件(组件的定义)
    ga统计
    token验证机制
    网站发布(项目上线流程)
    使用CSS将图片转换成黑白(灰色、置灰) & 毛玻璃效果
  • 原文地址:https://www.cnblogs.com/Ressed/p/9863482.html
Copyright © 2011-2022 走看看