题目给的容器很多,1e9,我们遍历肯定会超时。
但是他给的信息是,m只有3e5,且每次滴水都会滴在有水的地方,水满了之后也只会扩散到左右有水的地方。也就是说,只有有水的地方才是我们会用到的地方。
所以,我们只需要将有水的地方存起来即可,同时每次水满了之后会扩散到左右两个相邻有水的地方,所以还需要保存每个水滴左右相邻的水滴的位置。
每次有水滴满了,就将他加入优先队列,因为有多个水滴同时满了的话,从小的开始先扩散。
其他地方请见标注。
100分代码:
#include<bits/stdc++.h>
using namespace std;const int MAXN = 110;
const int MAXT = 10000;
const int N = 3e5+10;int n , m , c , p;
int vis[N];
map<int , int>mp; // 排序后的位置struct node{int p; // 位置int w; // 数量int pre;// 前驱int nxt;// 后继
}a[N];
bool cmp(node a , node b){return a.p < b.p;
}int main(){cin >> c >> m >> n;for(int i = 1 ; i <= m ; i++)cin >> a[i].p >> a[i].w;sort(a+1 , a+m+1 , cmp);for(int i = 1 ; i <= m ; i++){a[i].nxt = i+1;a[i].pre = i-1;mp[a[i].p] = i;}int res = m;priority_queue<int , vector<int> , greater<int>> q;for(int i = 1 ; i <= n ; i++){cin >> p;int id = mp[p];a[id].w++;if(a[id].w >= 5){q.push(id);a[id].w = 0;vis[id] = 1;}while(!q.empty()){res--;int x = q.top();q.pop();int pre = a[x].pre;int nxt = a[x].nxt;a[pre].nxt = nxt;a[nxt].pre = pre;if(pre >= 1){a[pre].w++;if(a[pre].w >= 5 && !vis[pre]){q.push(pre);a[pre].w = 0;vis[pre] = 1;}}if(nxt <= m){a[nxt].w++;if(a[nxt].w >= 5 && !vis[nxt]){q.push(nxt);a[nxt].w = 0;vis[nxt] = 1;}}}cout << res << endl;}return 0;
}