Cross Explosion

考查找。

线性查找上下左右四个方向看到的第一个的墙的位置复杂度O(n^2),在Q取到2e5的情况下直接爆掉。

这里应使用二分查找,对某一行、列进行二分,使用set实现墙的位置存储。

#include<bits/stdc++.h> 
using namespace std;
#define int long long
#define endl "\n"
const int p=1e9+7;
const int mod=998244353;
const int N=4e5+10;

void solve()
{
   int h,w,q;  cin>>h>>w>>q;
   vector<set<int> >g1(h+2),g2(w+2);

   for(int i=1;i<=h;i++)
   for(int j=1;j<=w;j++)
   {
    g1[i].insert(j);
    g2[j].insert(i);
   }

   while(q--)
   {
    
    int r,c; cin>>r>>c;
    
    if(g1[r].count(c)){
      g1[r].erase(c);
      g2[c].erase(r);
    }
    else{
        auto it=g2[c].lower_bound(r);
        if(it!=g2[c].begin()){
            int k=*prev(it);
            g2[c].erase(k);
            g1[k].erase(c);
        }

        it=g2[c].lower_bound(r);
        if(it!=g2[c].end()){
           int k=*it;
            g2[c].erase(k);
            g1[k].erase(c);
        }

        it=g1[r].lower_bound(c);
        if(it!=g1[r].begin()){
            int k=*prev(it);
            g1[r].erase(k);
            g2[k].erase(r);
        }

        it=g1[r].lower_bound(c);
        if(it!=g1[r].end()){
            int k=*it;
            g1[r].erase(k);
            g2[k].erase(r);
        }
    }
   }
   int ans=0;
   for(int i=1;i<=h;i++)
   ans+=g1[i].size();
   cout<<ans;
}

signed main()
{
//	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int t;
	t=1;
//	cin>>t;
	while(t--)
	{
		solve();
	}
	return 0;	
}

prev(it) :返回it的前一个元素迭代器

24/9/10

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值