zoukankan      html  css  js  c++  java
  • George and Cards

    Codeforces Round #227 (Div. 2) E:http://codeforces.com/contest/387/problem/E

    题意:给你一个n个数的序列,然后给你一个标准序列,现在然后删除原序列的一些数,让原序列变成标准序列。其中,每次查询可以选择一个连续的序列,然后要删除的数字必须是这个序列中的最小的那个。每一次删除,你可以获得这个长度的价值,问你最多可以得到多少价值。

    题解:首先,很明显,每次删除要从要删除的数中选择最小的来删除,而且每次删除就是以包含这个数为最小数的最大串。关键是怎么找到这个串。观察可以知道,举个例子,

    14 6
    7 6 10 9 11 8 14 3 1 13 12 4 5 2
    7 10 11 12 4 5
    
    假如说我们要删除8,那么肯定要找离8最近的并且比8小的,没有被删除的数的位子。得到这个区间之后,那么肯定是都是要删除的,要么事已经删除的,要么是没有删除的,那么真正的长度就是去掉那些删除元素的留下来长度。有了这些结论和想法之后。可以想到。每次从最小的数开始,用一个set维护不需要被删除的数的位子。如果当前的数是不要被删除的,那么就把这个数的位子放进set,然后如果这个数是要被删除的,就从set中找到比当前数位子大的位子,因为set中存的是比当前数小并且是不要被删除数的位子。所以lower_bound(ps[i]),得到是ps[i]右边最近的比i小不用被删除的数的位子,左移一位,那么得到就是ps[i]左边最近的比i小的不用被删除的数的位子。然后得到这个区间了,至于,那么已经被删除元素的,可以用树状数组来统计,都是log(n),总的复杂度nlog(n);
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<set>
     7 using namespace std;
     8 const int N=1e6+7;
     9 int ct[N];
    10 bool visit[N];
    11 int n,m,temp;
    12 int ps[N];
    13 long long ans;
    14 int lowbit(int x){
    15    return x&(-x);
    16 }
    17 void add(int x){
    18   while(x<=n){
    19     ct[x]++;
    20     x+=lowbit(x);
    21   }
    22 }
    23 int sum(int x){
    24    int ans=0;
    25    while(x>0){
    26     ans+=ct[x];
    27     x-=lowbit(x);
    28    }
    29    return ans;
    30 }
    31 int main(){
    32      while(~scanf("%d%d",&n,&m)){
    33         memset(ct,0,sizeof(ct));
    34         memset(ps,0,sizeof(ps));
    35         memset(visit,0,sizeof(visit));
    36         for(int i=1;i<=n;i++){
    37             scanf("%d",&temp);
    38             ps[temp]=i;
    39         }
    40         for(int i=1;i<=m;i++){
    41             scanf("%d",&temp);
    42             visit[temp]=1;
    43         }
    44         ans=0;
    45         set<int>Q;int l,r;
    46         for(int i=1;i<=n;i++){
    47             if(visit[i]==1){
    48                 Q.insert(ps[i]);
    49             }
    50             else{
    51                 set<int>::iterator it=Q.lower_bound(ps[i]);
    52                 if(it==Q.end()){
    53                     if(Q.size()==0){
    54                        r=n;
    55                        l=1;
    56                     }
    57                     else{
    58                         r=n;
    59                         l=(*(--it))+1;
    60                     }
    61                 }
    62                 else if(it==Q.begin()){
    63                     l=1;
    64                     r=(*it)-1;
    65                 }
    66                 else{
    67                     r=(*it)-1;
    68                     l=(*(--it))+1;
    69                 }
    70                // printf("%d %d %d
    ",i,l,r);
    71                 ans+=r-l+1;
    72                 ans-=sum(r);
    73                 ans+=sum(l-1);
    74                 add(ps[i]);
    75             }
    76         }
    77       printf("%I64d
    ",ans);
    78      }
    79 }
    View Code
     
  • 相关阅读:
    [转]Dokuwiki使用感受
    [转]认识与入门Markdown
    [转]2015深度学习回顾:ConvNet、Caffe、Torch及其他
    [转]Dokuwiki插件与主题推荐
    [转]okuwiki布署小记
    PHP环境配置
    keydown和keypress
    JavaScript优化参考
    IE兼容性标签和条件注释
    nodejs 简单http 文件上传demo
  • 原文地址:https://www.cnblogs.com/chujian123/p/3880066.html
Copyright © 2011-2022 走看看