• 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 }
  • 相关阅读:
    关于float与double
    【编程实践】母牛生小牛
    wlan的QOS配置
    C语言itoa函数和atoi 函数
    类似于QQ的简单的聊天代码
    多线程吃饺子练习
    线程练习
    接口练习
    电视练习
    5.22
  • 原文地址:https://www.cnblogs.com/swm8023/p/2701487.html
Copyright © 2020-2023  润新知