Hello 2023 D.Boris and His Amazing Haircut

简介: Hello 2023 D.Boris and His Amazing Haircut

题目

Problem - D - Codeforces

题意

  • 给两个长度为n的数组a,b,再给一个数组长度为m的数组x,表示m次操作
  • 每次操作把选择一个区间把a[l ~ r]中大于x[i]的变为x[j],否则不变
  • 问能否在m次操作内把数组a变为与数组b相等

思路

很容易知道,如果a[i] < b[i],一定不可能 显然要把所有a数组,对于b数组相同元素进行操作,可以找到一个一个点 b[i]!=a[i] b[i] != a[i]b[i]!=a[i],关于b[i] 为了节省次数,我们要尽可能的合并这些点,把b[i]相同的点,转化为区间,区间数量要小于x数组中b[i]的数量 所以关键操作就在如何合并b[i]相同的点 可以用区间查询的策略,找出相邻两个位置,如果之间最大的值小于等于两个端点,那么这两个点可以合并,否则不能合并 实现可以通过st表,线段树,树状数组等(可恶啊,比赛的时候智商变低,一直在想着怎么能朴素优化,没想到这么简单) 可以通过单调栈,单调递减找出上一个大于等于当前的位置,如果栈顶为空或者大于当前点,这个点需要的数量就加一 如果等于,说明可以合并,跳过

区间查询O(nlogn+mlogm)


const int N = 2e5+10,M = 20;
int a[N],b[N],x[N];
int st[N][M];
void ST(int n)//区间max
{
    //memset(st,0,sizeof st);
    for(int k = 0;k < M;k ++)
    {
        for(int i = 1;i <= n - (1<<k) + 1;i ++)
        {
            if(!k)st[i][k] = b[i];
            else{
                st[i][k] = max(st[i][k-1],st[i+(1<<(k-1))][k-1]);
            }
        }
    }
}
// int query(int l,int r)//区间max
// {
//     int t = M-1;
//     int res = 0;
//     while(t >= 0)
//     {
//         if(l + (1<<t) > r)t --;
//         else{
//             res = max(res,st[l][t]);
//             l += 1<<t;
//         }
//     }
//     return res;
// }
int query(int l, int r)
{
    int len = r - l + 1;
    int k = log(len) / log(2);
    return max(st[l][k], st[r - (1 << k) + 1][k]);
}
void solve() 
{
    map<int,vector<int>> tar;
    map<int,int> cnt;
    int n;cin >> n;
    fr(1,i,n+1)cin >> a[i];
    fr(1,i,n+1)cin >> b[i];
    int m;cin >> m;
    fr(1,i,m+1)cin >> x[i],cnt[x[i]] ++;
    
    fr(1,i,n+1)if(a[i] < b[i])
    {
        cout << "NO" << endl;
        return ;
    }
    fr(1,i,n+1)
    {
        if(a[i] != b[i])tar[b[i]].push_back(i);
    }
    
    ST(n);
    bool acc = 1;
    for(auto [key,y]:tar)
    {
        int num = 1;
        for(int i = 1;i < y.size();i ++)
        {
            //debug3(y[i-1],y[i],query(y[i-1],y[i]));
            if(query(y[i-1],y[i]) > key)num ++;
        }
        //debug4(key,num,cnt[key],y.size());
        if(num > cnt[key])acc = 0;
    }
    //for(auto [key,y]:tar)if(cnt[key])acc = 0;
    cout << (acc?"YES":"NO") << endl;
}

pps:st表第一次用,感觉有点像倍增

ps:for(auto [key,y]:tar)if(cnt[key])acc = 0;这样的用法居然在VScode里标错了,但是可以运行

单调栈(代码用了别人的,妙哉)

cpp

复制代码

#include<bits/stdc++.h>
using namespace std;
int T,n,a[200005],b[200005],m,x;
bool bb;
int main()
{
    scanf("%d",&T);
    while(T--){
        bb=0; map<int,int>mapp; stack<int>q;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",a+i);
        for(int i=1;i<=n;i++) scanf("%d",b+i);
        scanf("%d",&m);
        for(int i=1;i<=m;i++) scanf("%d",&x),mapp[x]++;
        for(int i=1;i<=n;i++){
            if(a[i]<b[i]){bb=1;break;}
            while(!q.empty()&&q.top()<b[i]) q.pop();
            if((q.empty()||(!q.empty()&&q.top()!=b[i]))&&a[i]>b[i]){
                q.push(b[i]);
                if(mapp[b[i]]<=0){bb=1;break;}
                mapp[b[i]]--;                    
            }
        }
        puts((bb?"NO":"YES"));
    }
}


相关文章
|
前端开发
《the Great Gatsby》Day 26
Gatsby告诉Daisy,她只要说自己从未爱过Tom,便能就此解脱,幸福地和自己在一起;但是当Tom说出曾经的种种,回忆淹没了Daisy,她没办法违背自己的内心——她曾深爱过Tom。Daisy说自己还是会离开Tom,Tom情急之下说出了Gatsby光鲜外表背后的那些不光彩的勾当。Daisy再一次恳求Tom带她回家,Tom却让Gatsby开车送她
123 0
《The Great Gatsby》Day 22
《The Great Gatsby》Day 22 2.大概内容 一度是灯火通明的Gatsby家,在一个夏夜突然暗淡下来,那些怀着希望而来的人们,看到这副景象也都失望地离开了。。。Nick开始以为Gatsby生病了或是去了外地,后来才
109 0
《The Great Gatsby》Day 18
Gatsby进屋后,尴尬又紧张地依靠在壁炉旁,不知该如何打破沉默,Nick看到两人都很拘谨的样子,说自己有点事就出门了。Nick回屋时看到Gatsby和Daisy正坐在沙发上小声而热切地交谈着,含情脉脉地望着对方,连Nick回来都不知道。雨停后,Gatsby又邀请Daisy和Nick去自己家参观。 3.好词佳句 (1)The rain was still falling,but the darknes
134 0
《The Great Gatsby》Day 13
pore n毛孔 v深思熟虑,审视 battalion n军队,部队 elicit v引出,诱出 cricket 板球,蟋蟀
113 0
《The Great Gatsby》Day 20
让Nick感到惊讶的是Tom Mr.Sloane和一个穿着马术服装的女子骑着马来到了Gatsby家,女子还邀请Gatsby和Nick去她家共进晚餐。Tom不放心Daisy自己一个人到处走动,便陪着她来到了Gatsby的一个聚会,聚会上Tom又是一如既往地到处调情,但这也同时给Daisy和Gatsby单独相处的机会
127 0
|
Windows
《The Great Gatsby》Day 16
Jordan向Nick讲述了一切:Gatsby和Daisy五年前就认识了,当时Gatsby是个军官,他们相爱了;然而Gatsby被调去海外,两人断了联系,Daisy之后便和Tom结婚了,结婚前夕Daisy收到了一封来信,十分伤心,灌醉了自己说着“改变主意了”,可她最终还是和Tom结婚了。Gatsby一直还爱着Daisy,所以想摆脱Nick邀请Daisy来家中喝下午茶,这样他就可以假装路过来见她一
180 0
《The Great Gatsby》Day 12
舞会快结束的时候,Jordan和Gatsby也从书房出来了,Jordan告诉Nick她刚刚听到了最不可思议的事,但是又故意卖关子不肯说说是什么;她被伙伴们簇拥着上了车,和Nick告别时叮嘱Nick一定要给她打电话,Nick和Gatsby道别后也回家了。生活一天天过去,Nick也渐渐爱上了纽约。
105 0
《The Great Gatsby》Day 21
在Gatsby的又一次party上,Daisy和Tom也应邀前来参加,一位又一位女客涂脂抹粉,男女狂欢的热闹繁华夜场生活反射出当时赤裸裸的美国梦。Gatsby因Tom去勾搭其
195 0
《The Great Gatsby》Day 14
大致内容 一天早晨,Gatsby开着他的定制轿车出现在Nick家门口,要带他一起去城里吃饭;在路上,Gatsby向Nick讲述自己的故事(他出身在中西部一个富有的家庭,在美国长大,又去了牛津三一学院读书,后来家人相继去世,他便继承了大笔遗产;后来参军,英勇善战,甚至获得了黑山共和国的荣誉勋章。)Gatsby还说有时要拜托Nick,但又执意要等到午饭后才说。 3.好词佳句
140 0
《The Great Gatsby》Day 15
Gatsby向Nick介绍了他的朋友Mr.Wolfsheim,Mr.Wolfsheim和Nick聊了一会就走了,Gatsby告诉Nick他就是当年操纵棒球联赛“黑袜联赛”的人。Nick发现Tom也在餐厅,带Gatsby过去打招呼,但是Gatsby看见
141 0