• 解题:HEOI 2012 采花


    题面

    题外话:LYD说他当时看错题了,考场爆零了,然后有了作诗这道题=。=

    离线处理询问,按右端点递增排序,然后对于每种花$flw[i]$,我们求一个$pre[flw[i]]$表示这种花上一次出现的位置。那么扫描每一朵花,然后一个询问右端点的花出现的贡献就是使得$[pre[pre[i]]+1,pre[i]]$这段可以多采到至少$1$朵花,当扫到询问左端点就单点统计答案。用一个数据结构进行区间修改+单点求和即可

    洛谷不知道为啥把数据加强到了$2*10^6$,听说是卡莫队(不知所淦),然后把正常的线段树也给卡掉了,遂稍微卡了卡常+O2,最慢一个点1600+ms水过(还可以继续优化的说)

     1 // luogu-judger-enable-o2
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=2000005;
     8 struct a{int l,r,id,ans;}p[N];
     9 int flw[N],pre[N],las[N],outp[N];
    10 int val[4*N],laz[4*N];
    11 int n,c,m;
    12 bool cmp(a x,a y)
    13 {
    14     return x.r==y.r?x.l<y.l:x.r<y.r;
    15 }
    16 bool com(a x,a y)
    17 {
    18     return x.id<y.id;
    19 }
    20 inline int read()
    21 {
    22     int ret=0;
    23     char ch=getchar();
    24     while(!isdigit(ch)) ch=getchar();
    25     while(isdigit(ch)) ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();
    26     return ret; 
    27 }
    28 inline void release(int nde,int l,int r)
    29 {
    30     if(laz[nde])
    31     {
    32         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
    33         laz[ls]+=laz[nde],laz[rs]+=laz[nde];
    34         val[ls]+=(mid-l+1)*laz[nde],val[rs]+=(r-mid)*laz[nde]; laz[nde]=0;
    35     }
    36 }
    37 void change(int nde,int l,int r,int nl,int nr)
    38 {
    39     if(l>nr||r<nl)
    40         return ;
    41     else if(l>=nl&&r<=nr)
    42         val[nde]+=r-l+1,++laz[nde];
    43     else
    44     {
    45         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; release(nde,l,r);
    46         change(ls,l,mid,nl,nr),change(rs,mid+1,r,nl,nr);
    47         val[nde]=val[ls]+val[rs];
    48     }
    49 }
    50 int query(int nde,int l,int r,int pos)
    51 {
    52     if(l==pos&&r==pos) return val[nde]; release(nde,l,r);
    53     int mid=(l+r)/2,lr=(pos<=mid),nd=lr?(nde<<1):(nde<<1|1);
    54     int nl=lr?l:(mid+1);int nr=lr?mid:r;
    55     return query(nd,nl,nr,pos);
    56 }
    57 int main ()
    58 {
    59     register int i,p1=1;
    60     n=read(),c=read(),m=read();
    61     for(i=1;i<=n;i++) flw[i]=read();
    62     for(i=1;i<=m;i++) p[i].id=i,p[i].l=read(),p[i].r=read();
    63     for(i=1;i<=n;i++) pre[i]=las[flw[i]],las[flw[i]]=i;
    64     sort(p+1,p+1+m,cmp);
    65     for(i=1;i<=n;i++)
    66     {
    67         change(1,1,n,pre[pre[i]]+1,pre[i]);
    68         while(p1<=m&&p[p1].r==i) 
    69             p[p1].ans=query(1,1,n,p[p1].l),p1++;
    70     }
    71     for(i=1;i<=m;i++) outp[p[i].id]=p[i].ans;
    72     for(i=1;i<=m;i++) printf("%d
    ",outp[i]);
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    SQL-LINQ-Lambda 语法对照
    C#.NET面向对象(语法点)
    4.5 基于STM32+MC20远程短信控制开关
    4.4 使用STM32控制MC20进行GPS帧数据解析
    4.3 使用STM32控制MC20进行GPRS通讯
    4.2 使用STM32控制MC20发送短信
    4.1 使用STM32控制MC20拨打电话
    3.6.使用STC89C52控制MC20解析GPS的经纬度数据上传到指定服务器
    3.5.基于STC89C52+MC20的短信远程控制开关LCD1602显示
    3.4 使用STC89C52控制MC20解析GPS的经纬度数据在LCD1602上显示
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9677863.html
Copyright © 2020-2023  润新知