求助Wa on#7
查看原帖
求助Wa on#7
555381
zlttcl楼主2024/1/28 22:19
//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
ll n, a[N], l[N], r[N], p[N], ans;
inline ll read(){
	ll x = 0, m = 1;
	char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') m = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * m;
}
inline void write(ll x){
	if(x < 0){
		putchar('-');
		write(-x);
		return;
	}
	if(x >= 10) write(x / 10);
	putchar(x % 10 + '0');
}
struct Code{
	ll lst, len, sum;
	bool operator <(const Code &x)const{
		return len < x.len || (len == x.len && lst > x.lst);
	}
};
priority_queue<Code> q;
signed main(){
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
    n = read();
    for(int i = 1; i <= n; ++ i) a[i] = read();
    int now = a[1], lst = 1;
    a[0] = -1314520, a[n + 1] = -1314521;
    for(int i = 2; i <= n + 1; ++ i){
        if(a[i] != now){
        	q.push(Code{lst, i - lst, now});
        	r[lst] = i - 1, l[i - 1] = lst;
        	p[lst] = i - lst;
        	now = a[i], lst = i;
		}
	}	
	while(!q.empty()){
		Code u = q.top(); q.pop();
//		cout << u.lst << ' ' << u.len << endl << endl;
//		for(int i = 1; i <= n; ++ i) cout << l[i] << ' ' << r[i] << endl;cout << endl;
		if(p[u.lst] != u.len) continue;
		++ ans;
		if(a[u.lst - 1] == a[u.lst + u.len]){
			p[l[u.lst - 1]] += p[u.lst + u.len];
			r[l[u.lst - 1]] = r[u.lst + u.len];
			q.push(Code{l[u.lst - 1], r[u.lst + u.len] - l[u.lst - 1] + 1, a[u.lst - 1]});
		}

	}
	write(ans);
	return 0;
}

思路就是优先队列,用双向链表存每一个块的左右端点,pip_i 表示以 ii 为左端点的当前块长,最后答案大了。

2024/1/28 22:19
加载中...