zoukankan      html  css  js  c++  java
  • HDU 4398 Template Library Management [贪心+线段树]

      经典页面调度问题,理想算法就是移出从现在开始最久未使用的。

      线段树中存正在使用的页面(题中是模版。。)下次出现的时间,每次选出现时间最晚的扔掉。如果遇到一个已经在内存中的页面,也要跟新该页面在线段树中的值。

      

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #define lson l,m,p<<1
     5 #define rson m+1,r,p<<1|1
     6 #define calm l+r>>1
     7 #define MAXN 100005
     8 int n,m,x[MAXN];
     9 int ld[MAXN],next[MAXN],pos[MAXN],has[MAXN];
    10 int maxv[MAXN<<2],maxid[MAXN<<2];
    11 int binser(int x){
    12     int min=1,max=n+1,mid=min+max>>1;
    13     for(;mid!=min;mid=min+max>>1){
    14         if(ld[mid]<=x)min=mid;
    15         else max=mid;
    16     }
    17     return ld[mid]==x?mid:-1;
    18 }
    19 void pushup(int p){
    20     if(maxv[p<<1]>maxv[p<<1|1])
    21         maxv[p]=maxv[p<<1],maxid[p]=maxid[p<<1];
    22     else
    23         maxv[p]=maxv[p<<1|1],maxid[p]=maxid[p<<1|1];
    24 }
    25 void update(int L,int v,int l,int r,int p){
    26     if(l==r){
    27         maxv[p]=v,maxid[p]=L;
    28         return;
    29     }
    30     int m=calm;
    31     if(L<=m)update(L,v,lson);
    32     if(L>m)update(L,v,rson);
    33     pushup(p);
    34 }
    35 int solve(){
    36     memset(has,0,sizeof has);
    37     memset(maxv,0,sizeof maxv);
    38     int rel=0;
    39     for(int i=1;i<=m;i++){
    40         int id=binser(i);
    41         if(id==-1){rel++;continue;}
    42         update(id,pos[id],1,n,1);
    43         has[id]=1;
    44     }
    45     int ans=0;
    46     for(int i=1;i<=n;i++){
    47         int id=x[i];
    48         if(has[id]==0){
    49             update(id,next[i],1,n,1);
    50             has[id]=1;
    51             ans++;
    52             //考虑先把没用的丢掉(一直没有的)
    53             if(rel){rel--;continue;}
    54             //将最远未出现的丢掉
    55             has[maxid[1]]=0;
    56             update(maxid[1],0,1,n,1);
    57         }else{
    58             update(id,next[i],1,n,1);
    59         }
    60     }
    61     return ans;
    62 }
    63 void getnext(){
    64     memset(pos,0x3f,sizeof pos);
    65     for(int i=n;i>=1;i--){
    66         next[i]=pos[x[i]];
    67         pos[x[i]]=i;
    68     }
    69 }
    70 
    71 int main(){
    72     //freopen("test.in","r",stdin);
    73     while(scanf("%d%d",&n,&m)!=EOF){
    74         for(int i=1;i<=n;i++)
    75             scanf("%d",&x[i]),ld[i]=x[i];
    76         std::sort(ld+1,ld+n+1);
    77         for(int i=1;i<=n;i++)x[i]=binser(x[i]);
    78         getnext();
    79         int x=solve();
    80         printf("%d\n",x);
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    在HTML网页中嵌入脚本的方式
    纪念品分组(贪心、排序)
    合并果子(STL优先队列)
    铺地毯(取最上层的地毯)
    多项式方程的输出
    BF算法(蛮力匹配)
    数位的处理
    两个数的差
    多项式计算器
    随机数生成器java实现
  • 原文地址:https://www.cnblogs.com/swm8023/p/2701487.html
Copyright © 2011-2022 走看看