• noi.ac day6t3 color


    传送门

    分析

    将询问离线,枚举右端点。新加入一个右端点i时,假设离i第t近的同色位置为p,t+1近的是q,则当i是右端点时,(q,p]的点可以作为左端点。

    注意对于一个点离它第t近的同色点可以用队列维护求得

    之后用树状数组差分一下就可以了

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    struct node {
        int le,ri,id;
    };
    node a[500010];
    vector<int>q[500010];
    int C[500010],d[500010],n,m,k,t,ans[500010];
    int nxt[500010],fa[500010],pre[500010],ppre[500010],is[500010];
    inline bool cmp(const node x,const node y){return x.ri<y.ri;}
    inline int lb(int x){return x&(-x);}
    inline void add(int x,int k){while(x<=n)d[x]+=k,x+=lb(x);}
    inline int Q(int x){int res=0;while(x)res+=d[x],x-=lb(x);return res;}
    int main(){
        int i,j=1;
        scanf("%d%d%d%d",&n,&m,&k,&t);
        for(i=1;i<=n;i++)scanf("%d",&C[i]);
        for(i=1;i<=m;i++)scanf("%d%d",&a[i].le,&a[i].ri),a[i].id=i;
        sort(a+1,a+m+1,cmp);
        for(i=1;i<=k;i++)q[i].push_back(0);
        for(i=1;i<=n;i++){
          int x=C[i],s=q[x].size();
          q[x].push_back(i);      
          if(s>=t)add(q[x][s-t]+1,1),add(q[x][s-t+1]+1,-1);
          if(s>t)add(q[x][s-t-1]+1,-1),add(q[x][s-t]+1,1);
          for(j;j<=m;j++)
              if(a[j].ri==i)ans[a[j].id]=Q(a[j].le);
              else break;
        }
        for(i=1;i<=m;i++)printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    [翻译]使用设计模式简化.NET中菜单和Form元素之间的关系
    [AWDwR4]13章出错 protect_against_forgery
    使用存储过程(22)
    建立数据库连接(19)
    对数据库添加数据(21)
    ADO.NET常用对象(18)
    数据展现Repeater控件(25)
    content控件(24)
    对数据库增加数据(21)
    行为存储过程(23)
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9821492.html
Copyright © 2020-2023  润新知