2019牛客第三场

Planting Trees

思路:枚举子矩形上下边,再尺取法+单调队列求合法的最长的宽

AC代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
 
int n,m,a[505][505];
int q1[505],q2[505];
int maxn[505],minn[505];
 
int main()
{
    int t;scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a[i][j]);
            }
        }
 
        int ans=0;
        for(int i=1;i<=n;i++){
            memset(maxn,0,sizeof(maxn));
            memset(minn,0x3f,sizeof(minn));
            for(int j=i;j<=n;j++){
                int h1=1,t1=0;
                int h2=1,t2=0;
                int l=1;
                for(int k=1;k<=n;k++){
                    maxn[k]=max(maxn[k],a[j][k]);
                    minn[k]=min(minn[k],a[j][k]);
 
                    while(h1<=t1&&maxn[q1[t1]]<=maxn[k]) t1--;
                    q1[++t1]=k;
                    while(h2<=t2&&minn[q2[t2]]>=minn[k]) t2--;
                    q2[++t2]=k;
 
                    while(l<=k&&maxn[q1[h1]]-minn[q2[h2]]>m){
                        l++;
                        if(q1[h1]<l) h1++;
                        if(q2[h2]<l) h2++;
                    }
                    ans=max(ans,(k-l+1)*(j-i+1));
                }
            }
        }
 
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

LRU management

思路:链表模拟增删,Trie树定位字符串的下标

AC代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

int num=0,st=0,ed=0,sz=0,L[500005*2],R[500005*2],data[500005*2],trie[500005*2];
int tot=1,pos[500005*10],son[500005*10][10];

void init(){
  for(int i=1;i<=tot;i++){
    for(int j=0;j<10;j++) son[i][j]=0;
    pos[i]=0;
  }
  tot=1;

  for(int i=0;i<500005*2;i++) L[i]=R[i]=data[i]=trie[i]=0;
  num=st=ed=sz=0;
}

void Erase(int id){
  int pre=L[id],succ=R[id];
  if(pre) R[pre]=succ;
  if(succ) L[succ]=pre;
  if(id==st) st=succ;
  if(id==ed) ed=pre;
  sz--;
}

void Insert(int id,int v){
  data[id]=v;
  if(!st) st=ed=id;
  else R[L[id]=ed]=id,ed=id;
  sz++;
}

void InsertTrie(char s[],int id){
  int p=1;
  for(int i=0;s[i];i++){
    if(!son[p][s[i]-'0']) son[p][s[i]-'0']=++tot;
    p=son[p][s[i]-'0'];
  }
  pos[p]=id;
  trie[id]=p;
}

int SearchTrie(char s[]){
  int p=1;
  for(int i=0;s[i];i++){
    p=son[p][s[i]-'0'];
    if(!p) break;
  }
  return pos[p];
}

int main()
{
    int t;scanf("%d",&t);
    while(t--){
        init();
        int q,m;scanf("%d%d",&q,&m);

        while(q--){
          int op;scanf("%d",&op);
          char s[10];scanf("%s",s);
          int v;scanf("%d",&v);

          int id=SearchTrie(s);
          if(op==0){
            if(id) v=data[id],Erase(id);
            else if(sz==m) pos[trie[st]]=0,Erase(st);

            num++;
            Insert(num,v);InsertTrie(s,num);
            printf("%d\n",v);
          }
          else{
            if(id==0||(v==-1&&L[id]==0)||(v==1&&R[id]==0)) puts("Invalid");
            else{
                if(v==-1) id=L[id];
                if(v==1) id=R[id];
                printf("%d\n",data[id]);
            }
          }
        }
    }
    return 0;
}
View Code

 

posted @ 2019-07-26 14:45  l..q  阅读(137)  评论(0编辑  收藏  举报