zoukankan      html  css  js  c++  java
  • Codeforces 786 C. Till I Collapse

    题目链接:http://codeforces.com/contest/786/problem/C


    大力膜了一发杜教的代码感觉十分的兹瓷啊!

      我们知道如果$k$是给定的我们显然是可以直接一遍$O(n)$的贪心扫过去的,那么问题很显然的变成了支持一个数据结构,维护一段区间内不同数字的个数(事实上是固定左端点求最远的右端点使得这段区间内不同数字的个数小于等于$k$)。嗯,很可以,如果写过HH的项链的话你就有可能.....

         HH的项链是有莫队做法和离线询问预处理$next$数组并用树状数组维护两种做法的,考虑如何转换第二种做法。(${next}$数组表示与第$i$个点颜色相同的在$i$之后的第一个点的位置)

      这里离线询问显然是不现实的(不知道要询问哪一些区间),考虑我们不是要做$n$次么,每一次的询问都是不停的往右边跳,所以拿一根扫描线从左到右扫过去,对于每一个位置做以这个位置为左端点的询问,然后把这个询问丢到查询出来的右端点的右边那一个点上去,用一个树状数组维护每个颜色出现的位置,扫描线扫过一个点之后消除这个点所在位置的影响,增加这个点的$next$的点所在位置的影响。树状数组查询的时候利用它的性质倍增的查询,就不需要二分了。

      一共有$n$次从左往右的跳跃,所以总跳跃的次数是${O(nlogn)}$的,树状数组利用倍增查询的复杂度是${O(logn)}$的,最后复杂度${O(nlog^{2}n)}$。


     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<map>
     8 #include<cstring>
     9 using namespace std;
    10 #define maxn 1001000
    11 #define TIMES 17
    12 #define llg int
    13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    14 llg n,m,a[maxn],k,sum[maxn],c[maxn],xian[maxn],nextt[maxn],ans[maxn];
    15 vector<llg>f[maxn];
    16 
    17 inline int getint()
    18 {
    19        int w=0,q=0; char c=getchar();
    20        while((c<'0' || c>'9') && c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); 
    21        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); return q ? -w : w;
    22 }
    23 
    24 llg lowbit(llg x) {return x&-x;}
    25 
    26 void add(llg x,llg val) {for (;x<=n+1;x+=x&-x) c[x]+=val;}
    27 
    28 llg find (llg x)
    29 {
    30     llg pos=0;
    31     for (llg i=TIMES;i>=0;i--)
    32     {
    33         if (pos+(1<<i)<=n+1 && c[pos+(1<<i)]<x) 
    34             x-=c[pos+(1<<i)],pos+=(1<<i);
    35     }
    36     return pos+1;
    37 }
    38 
    39 int main()
    40 {
    41     yyj("E");
    42     cin>>n;
    43     for (llg i=1;i<=n;i++) a[i]=getint();
    44     for (llg i=1;i<=n+1;i++) xian[i]=n+1;
    45     for (llg i=n+1;i>=1;i--) 
    46     {
    47         nextt[i]=xian[a[i]];
    48         xian[a[i]]=i;
    49     }
    50     
    51     for (llg i=1;i<=n+1;i++) add(xian[i],1),f[1].push_back(i);;
    52     for (llg i=1;i<=n;i++)
    53     {
    54         llg w=f[i].size();
    55         for (llg j=0;j<w;j++)
    56         {
    57             llg d=f[i][j];
    58             llg wz=find(d+1);
    59             ans[d]++;
    60             f[wz].push_back(d);
    61         }
    62         add(i,-1),add(nextt[i],1);
    63     }
    64     for (llg i=1;i<=n;i++) printf("%d ",ans[i]);
    65     return 0;
    66 }
  • 相关阅读:
    Golang mysql数据库
    C++ list结构体变量排序
    VS2013 ERROR MSB8020
    error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation
    error C2664: “FILE *fopen(const char *,const char *)”: 无法将参数 1 从“LPCTSTR”转换为“const char *”
    error C4430: missing type specifier
    虚拟地址转物理地址
    vs2013 x64 编译汇编代码
    fs寄存器相关,PEB,TEB
    boost 1.57 vs2013 编译
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6611459.html
Copyright © 2011-2022 走看看