题解 | #不点两面(hard version)#

不点两面(hard version)

https://www.nowcoder.com/practice/c49e65f6b73c491ab96840cbd230b2f1

这题核心就一句:
一个数字 x 安不安全,只看牌河里有没有 x-3x+3,和张数本身没关系。

所以我们维护两类信息:

  • c[v]:牌河里数字 v 现在有几张(多重集合计数)。
  • s[x]:当前有多少个“活跃数字”在保护 x
    也就是有多少个 v 满足 v-3=xv+3=xc[v]>0

再维护一个总答案 ans,表示当前有多少个 x 满足 s[x]>0(即安全牌种数)。

每次操作只会影响两个位置:num-3num+3,所以可以做到 O(1) 更新。

1)加入一张 num

  • 如果 c[num] 原来是 0,说明这个数字从“不活跃”变“活跃”,它会新保护:
    • num-3
    • num+3
  • 对这两个位置做 s[x]++
    • s[x] 从 0 变 1,ans++
  • 最后 c[num]++

如果 c[num] 原来就大于 0,这次加入不会新增保护范围,不用改 s

2)移出一张 num

  • c[num]--
  • 只有当 c[num] 从 1 变 0 时,num 才从“活跃”变“不活跃”,它对
    • num-3
    • num+3 的保护需要取消
  • 对这两个位置做 s[x]--
    • s[x] 从 1 变 0,ans--

边界上注意一下:num-3num+3 可能不在 [1,m],这种直接忽略。

复杂度

  • 每次操作最多改 2 个位置,时间 O(1)
  • 总时间 O(q)
  • 空间 O(m)
#include<bits/stdc++.h>
using namespace std;

using ll=long long;
using ull=unsigned long long;
using ld=long double;
using pii=pair<int,int>;
using pll=pair<ll,ll>;
using vi=vector<int>;
using vvi=vector<vector<int>>;
using vll=vector<ll>;
using vvll=vector<vector<ll>>;
using vc=vector<char>;
using vs=vector<string>;
using vb=vector<bool>;
using vpii=vector<pii>;
using vpll=vector<pll>;

const int INF=1e9;
const ll LINF=4e18;
const int MOD=1e9+7;
const int MOD2=998244353;

#define IOS ios::sync_with_stdio(false); cin.tie(nullptr);
#define endl '\n'
#define all(x) x.begin(),x.end()
#define ral(x) x.rbegin(),x.rend()
#define fi first
#define se second
#define fix(x) fixed<<setprecision(x)

ll gcd(ll a,ll b){
	return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
	return a/gcd(a,b)*b;
}

ll qpow(ll a,ll b,ll mod=MOD){
	ll res=1;
	a%=mod;
	while(b){
		if(b&1)res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}

ll modinv(ll a,ll p=MOD){
	return qpow(a,p-2,p);
}

struct Node{
	int a,b;
	
	bool operator<(const Node &y)const{
		return b>y.b;
	}
};

void solve(){
    int m,q;cin>>m>>q;
    vi c(m+1),s(m+1);
    int ans=0;
    auto add=[&](int x){
        if(x<1||x>m)return;
        if(s[x]==0)++ans;
        ++s[x];
    };
    auto del=[&](int x){
        if(x<1||x>m)return;
        --s[x];
        if(s[x]==0)--ans;
    };
    for(int i=1;i<=q;++i){
        int op,num;cin>>op>>num;
        if(op==1){
            if(c[num]==0){
                add(num-3);
                add(num+3);
            }
            ++c[num];
        }else{
            --c[num];
            if(c[num]==0){
                del(num-3);
                del(num+3);
            }
        }
        cout<<ans<<endl;
    }
}

int main(){
	IOS;
	int _=1;//cin>>_;
	while(_--){
		solve();
	}
	return 0;
}
全部评论

相关推荐

面试官人很好!!!刚开始面试的时候其实超级超级紧张,但是面试官会诱导我回答,越聊越轻松。无算法无手撕。无自我介绍1.&nbsp;面试官自我介绍,给我介绍团队部门和业务(一个偏ToD基础设施,一个类claude)2.&nbsp;日常开发中你是怎么用ai的?3.&nbsp;你是怎么进行测试的?(tips:其实面试官从这里开始就想问我workflow,一直在诱导我回答)我:就是让ai编写一些测试脚本去处理正常情况和边界情况面:那你这样子每次手动让ai去编写测试代码不会很繁琐嘛?那如果现在已经有了一个相关的Skill你会怎么用他?我:(叽里呱啦一大堆,我大概讲了一下这个skill应该做什么事情,讲了讲渐进式加载skill)面:那你能确保这个skill一定能执行嘛?我:我们可以用workflow,主流程固定,节点任务交给agent或者llm面:我想听的就是这个,那workflow怎么用呢?我:这确实不知道面:我们可以把workflow写到system&nbsp;prompt中4.&nbsp;你用ai到现在花了多少钱?(一分钱没花,这里还唠了一会)5.&nbsp;项目中的打字机效果是怎么实现的?6.&nbsp;打字机的帧率是多少,是怎么计算的?7.&nbsp;markdown渲染你有没有什么安全措施?怎么防XSS(gfm白名单)8.&nbsp;CSFR攻击9.&nbsp;为什么要用SSE做ai输出,不用websocket?10.&nbsp;项目:ai生成歌曲肯定需要一定的事件,你怎么让用户等待更加舒畅?11.&nbsp;等待进度条的当前task是怎么做的?(SSE&nbsp;自定义事件)12.&nbsp;为什么播放器要全局状态管理?13.&nbsp;假设我现在要做一个效果,就是根据音乐有音波的震动感,你会怎么做,谈谈思路就可以。我:1.用现成的库。2.每隔0.5s或者固定时间对某个节点进行分析音乐特征作为主波频,小波频可以用噪声模拟。面:音乐文件是可以解析成数组的,里面有音乐相关的特征信息(感觉运气很好啊,因为面试官也做过类似的项目所以比较感兴趣)14.&nbsp;为什么你的项目要用Next.js,这里我吐槽了一波SSR很恶心,很多浏览器的api都不能用,面试官告诉我那就是SSR用的地方不对,确实醍醐灌顶了,有高交互的地方确实不应该也不适合使用SSR15.&nbsp;你知道哪些性能指标呢?你是怎么监测的呢?16.&nbsp;&nbsp;我看你简历上写了擅长性能优化,跟我说说你怎么做的吧。(因为我们的服务器很差,我做了超级多的性能优化,我个人觉得这里答得蛮不错的,面试官说很少人会写这个,答出来会很加分)17.&nbsp;还有一些个别问题吧,刚开始的时候太紧张了,确实不记得了录音了。。。18.&nbsp;你觉得ai会取代前端嘛?19.&nbsp;你说你更喜欢美学和设计之类的,你了解过哪些动画库或者UI库嘛?20.&nbsp;通知一面过了(真的开心坏了哈哈哈哈哈哈哈)反问:1.&nbsp;如果能顺利通过面试的话,老师您更推荐我去哪个部门?2.&nbsp;大厂的开发流程协作模式是怎么样的?3.&nbsp;我现在用ai有个问题,日常开发中使用ai,如果代码是ai写的我会有深深的愧疚感,但是又不能不用。用了ai写代码,代码能力就慢慢地下降了,导致进一步使用ai,形成恶性循环,不知道老师您是怎么看的?(随个简历和下一场面试邀请)
晨时念:羡慕期待明天我也是这样
点赞 评论 收藏
分享
评论
3
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务