魔法学院
题目描述:
思路1: 差分 + 贪心
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m;
int l, r;
char p;
vector<pii>tr[200];
int ans[MAX];
int d[200050];
void work(){
cin >> n >> m;
for(int i = 1; i <= n; ++i){
cin >> p;
ans[i] = (int)p;
}
for(int i = 1; i <= m; ++i){
cin >> l >> r >> p;
tr[(int)p].push_back(m_p(l, r));
}
for(int i = 33; i <= 126; ++i){
mem(d, 0);
for(auto [l, r] : tr[i]){
++d[l];--d[r + 1];
}
for(int j = 1; j <= n; ++j){
d[j] += d[j - 1];
if(d[j])ans[j] = max(ans[j], i);
}
}
ll sum = 0;
for(int i = 1; i <= n; ++i)sum += ans[i];
cout << sum << endl;
}
int main(){
io;
work();
return 0;
}
思路2:贪心 + 线段树区间覆盖
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ls p<<1
#define rs p<<1|1
#define inf 0x3f3f3f3f
#define mod 1000000007
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 500000 + 50
int n, m, k, op;
struct ran{
int l, r, val;
bool operator <(const ran &x)const{
return val < x.val;
}
}ar[MAX];
ll sum[MAX];
int la[MAX];
inline void pushup(int p){
sum[p] = sum[ls] + sum[rs];
}
inline void built(int p, int l, int r){
if(l == r){
sum[p] = la[p] = 0;
return;
}
int mid = (l + r) / 2;
built(ls, l, mid);
built(rs, mid + 1, r);
pushup(p);
}
inline void cal_lazy(int p, int len, int x){
la[p] = x;
sum[p] = 1ll * len * x;
}
inline void pushdown(int p, int len){
if(la[p]){
cal_lazy(ls, len - len / 2, la[p]);
cal_lazy(rs, len / 2, la[p]);
la[p] = 0;
}
}
inline void update(int p, int l, int r, int s, int t, int x){
if(l >= s && t >= r){
cal_lazy(p, r - l + 1, x);
return;
}
pushdown(p, r - l + 1);
int mid = (l + r) / 2;
if(mid >= s)update(ls, l, mid, s, t, x);
if(mid < t)update(rs, mid + 1, r, s, t, x);
pushup(p);
}
inline ll getsum(int p, int l, int r, int s, int t){
if(l >= s && t >= r){
return sum[p];
}
pushdown(p, r - l + 1);
ll sum = 0;
int mid = (l + r) / 2;
if(mid >= s)sum += getsum(ls, l, mid, s, t);
if(mid < t)sum += getsum(rs, mid + 1, r, s, t);
return sum;
}
void work(){
cin >> n >> m;
char p;
for(int i = 1; i <= n; ++i){
cin >> p;
ar[i].l = ar[i].r = i;
ar[i].val = (int)p;
}
for(int i = 1; i <= m; ++i){
cin >> ar[i + n].l >> ar[i + n].r;
cin >> p;
ar[i + n].val = (int)p;
}
sort(ar + 1, ar + 1 + m + n);
built(1, 1, n);
for(int i = 1; i <= n + m; ++i){
update(1, 1, n, ar[i].l, ar[i].r, ar[i].val);
}
cout << getsum(1, 1, n, 1, n) << endl;
}
int main(){
work();
return 0;
}
思路3: 贪心 + 并查集
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 300000 + 50
int n, m;
char p;
char c[MAX];
int fa[MAX];
inline int getfa(int x){
return fa[x] == x ? x : fa[x] = getfa(fa[x]);
}
struct ran{
int l, r, p;
}tr[MAX];
bool cmp(ran a, ran b){
return a.p > b.p;
}
int ans[MAX];
void work(){
cin >> n >> m;
for(int i = 1; i <= n; ++i)cin >> c[i];
for(int i = 1; i <= m; ++i){
cin >> tr[i].l >> tr[i].r >> p;
tr[i].p = (int)(p);
}
for(int i = 1; i <= n + 1; ++i)fa[i] = i;
sort(tr + 1, tr + 1 + m, cmp);
for(int i = 1; i <= m; ++i){
auto [l, r, z] = tr[i];
l = getfa(l);
while (l <= r) {
ans[l] = max(ans[l], z);
fa[l] = l + 1;
l = getfa(l + 1);
}
}
ll cnt = 0;
for(int i = 1; i <= n; ++i){
cnt += max(ans[i], (int)c[i]);
}
cout << cnt << endl;
}
int main(){
io;
work();
return 0;
}
思路4:珂朵莉树 + “玄学优化”
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inf 0x3f3f3f3f
#define mod 1000000007
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define it set<ran>::iterator
typedef long long ll;
typedef pair <int,int> pii;
#define MAX 20000000 + 50
int n, m;
int l, r;
vector<pii>s[130];
char ss[MAX];
struct ran{
int l, r;
mutable int val;
ran(int L, int R = -1, int Val = 0){
l = L;r = R;val = Val;
};
bool operator <(const ran &x)const{
return l < x.l;
}
};
set<ran>tr;
it split(int pos){
if(pos > n)return tr.end();
it itt = tr.lower_bound(pos);
if(itt != tr.end() && itt->l == pos)return itt;
--itt;
int l = itt->l, r = itt->r, v = itt->val;
tr.erase(itt);
tr.insert(ran(l, pos - 1, v));
return tr.insert(ran(pos, r, v)).first;
}
void emerge(int l, int r, int v){
it itr = split(r + 1), itl = split(l);
tr.erase(itl, itr);
tr.insert(ran(l, r, v));
}
ll getans(){
ll ans = 0;
for(auto [l, r, v] : tr){
for(int i = l; i <= r; ++i){
ans += max(v, (int)ss[i]);
}
}
return ans;
}
void work(){
scanf("%d%d", &n, &m);
scanf("%s", ss + 1);
tr.insert(ran(1, n, 0));
for(int i = 1; i <= m; ++i){
char p[3];
scanf("%d%d", &l, &r);
scanf("%s", p);
s[(int)p[0]].push_back(m_p(l, r));
}
for(int i = 33; i <= 126; ++i){
for(auto [l, r] : s[i]){
emerge(l, r, i);
}
}
printf("%lld\n", getans());
}
int main(){
work();
return 0;
}