J. Jewel Grab

Tartarus
_Wallace_


转化询问:对于一个询问 [s,k],找到一个最长的区间 [s,t],满足区间中出现次数超过一次的元素,的出现次数减一,的和,不超过 k。

对于该区间[s,t] 区间数颜色:也就是每种颜色只算一个权值求最大和(显然每种颜色都取最大的权值)于是有下面转化:对于所有区间中出现次数超过一次的元素,找出其中权值最大的求和;对其他的元素(仅仅出现一次)直接求和。计算最终结果。


区间数颜色显然要维护一个pre[x]数组表示前一个出现c[x]的位置在哪?

首先我们考虑如何找到区间的端点t,也就是找到[s,t]这个区间。由于k非常小,考虑一次只忽略一个宝石,也就是每次找到第一个 pre[x]>s 的 x 即可,那么由于pre[x]和x都在所考虑区间内部,于是就需要多一次忽略。

显然c[x]就是出现次数超过一次的元素 于是只需要记录mc[c[x]]每次选择最大的。而对于[cur,x)这段区间都是其他的元素(仅仅出现一次)直接区间求和即可计算贡献。


考虑如何修改?

每当修改一个位置的颜色最多会有3个位置的pre[]发生改变:

可以考虑用一个双链表pre[],nxt[]维护一下。详细参考代码,代码都是抄第一篇博客的。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
const int N=200010;int n,m;
int pre[N],last[N],nxt[N];
int c[N];ll v[N],mc[N];
set<int> cp[N];
void prework()
{memset(last,-1,sizeof last);for(int i=n;i>=1;i--){nxt[i]=last[c[i]];last[c[i]]=i;}memset(last,-1,sizeof last);for(int i=1;i<=n;i++) {pre[i]=last[c[i]];last[c[i]]=i;cp[c[i]].insert(i);}
}
struct node
{int l,r;int v;ll s;
}t[N<<2];
void pushup(int u)
{t[u].v=max(t[u<<1].v,t[u<<1|1].v);t[u].s=t[u<<1].s+t[u<<1|1].s;
}
void build(int u,int l,int r)
{t[u]={l,r};if(l==r){t[u].v=pre[l];t[u].s=v[l];return;}int mid=l+r>>1;build(u<<1,l,mid),build(u<<1|1,mid+1,r);pushup(u);
}
void modify(int u,int p)
{if(t[u].l==t[u].r) {t[u].v=pre[p];t[u].s=v[p];return;}int mid=t[u].l+t[u].r>>1;if(p<=mid) modify(u<<1,p);else modify(u<<1|1,p);pushup(u);
}
ll query(int u,int l,int r)
{if(l<=t[u].l&&t[u].r<=r) return t[u].s;int mid=t[u].l+t[u].r>>1;ll v=0;if(l<=mid) v+=query(u<<1,l,r);if(r>mid) v+=query(u<<1|1,l,r);return v;
}
int find(int u,int s,int p)
{if(t[u].l==t[u].r) return t[u].l;int mid=t[u].l+t[u].r>>1;int pos=-1;if(t[u<<1].v>=s&&p<=mid)    pos=find(u<<1,s,p);if(pos!=-1) return pos;if(t[u<<1|1].v>=s)pos=find(u<<1|1,s,p);return pos;
}
int main()
{n=rd(),m=rd();for(int i=1;i<=n;i++) c[i]=rd(),v[i]=rd();prework();build(1,1,n);while(m--){int op=rd();if(op==1){int x=rd(),c0=rd(),v0=rd();cp[c[x]].erase(x);// 最后一次出现的c[x]的位置if(last[c[x]]==x) last[c[x]]=pre[x];v[x]=v0;c[x]=c0;// 删除的修改// 链表的一些删除操作if(nxt[x]!=-1) {if(pre[x]!=-1) {nxt[pre[x]]=nxt[x];pre[nxt[x]]=pre[x];modify(1,nxt[x]);// nxt[x]的pre[]发生改变需要维护}else{pre[nxt[x]]=-1;modify(1,nxt[x]);}}else{if(pre[x]!=-1) nxt[pre[x]]=-1;}// 插入的修改int pos;set<int>::iterator it;it=cp[c0].lower_bound(x);// 插入在末尾if(it==cp[c0].end()){nxt[x]=-1;pre[x]=last[c0];if(pre[x]!=-1) nxt[pre[x]]=x;modify(1,x);}else{pos=*it;if(pre[pos]!=-1) //插入不在开头{nxt[pre[pos]]=x;pre[x]=pre[pos];modify(1,x);}// 插入在开头else{pre[x]=-1;modify(1,x);}nxt[x]=pos;pre[pos]=x;modify(1,pos);}cp[c0].insert(x);last[c0]=max(last[c0],x);}else{int s=rd(),k=rd();vector<int> col;int cur=s;ll ans=0;for(int j=0;j<=k&&cur<=n;j++){int pos=find(1,s,cur);if(pos==-1) {ans+=query(1,cur,n);break;}col.push_back(c[pos]);if(j<k){// 出现一次直接选if(mc[c[pos]]==0) mc[c[pos]]=v[pre[pos]];// 出现第二次考虑与第一次出现的比较if(v[pos]>mc[c[pos]]){ans-=mc[c[pos]];ans+=v[pos];mc[c[pos]]=v[pos];}}ans+=query(1,cur,pos-1);// [cur,pos-1]都是第一次出现cur=pos+1;}printf("%lld\n",ans);for(int u:col) mc[u]=0;}}return 0;
}

太难了吧。。
要加油哦~

The 2020 ICPC Asia Macau Regional Contest J. Jewel Grab(数颜色+链表)相关推荐

  1. 并查集 ---- 扩展域并查集判二分图 + 循环模拟字典树 The 2020 ICPC Asia Macau Regional Contest C. Club Assignment (详解)

    题目链接 题目大意: 有n个数,现在要把他们拆分成两个集合,假设S为集合,有如下定义: f(S)={min(x⊕y)∣x,y∈S,andx!=y}f(S)=\{min(x\oplus y)|x,y\i ...

  2. The 2020 ICPC Asia Macau Regional Contest A. Accelerator(分治+NTT)

    A. Accelerator 实质上就是求n个多项式相乘 (a1+x)(a2+x)-(an+x)(a_1+x)(a_2+x)\dots(a_n+x) (a1​+x)(a2​+x)-(an​+x) 对于 ...

  3. The 2020 ICPC Asia Macau Regional Contest

    文章目录 前言 D.Artifacts F. Fixing Networks L. Random Permutation 总结 前言 vp D.Artifacts 题意:阅读理解,字符串中提取出来对应 ...

  4. 2018 ICPC Asia Jakarta Regional Contest J. Future Generation 状压dp

    传送门 文章目录 题意: 思路: 题意: 给你nnn个串,字符集是a−za-za−z,让你在每个串种选择一个子序列,保证对于i<j,si<sji<j,s_i<s_ji<j ...

  5. The 2020 ICPC Asia Shenyang Regional Programming Contest I题 Rise of Shadows(数论)

    题目链接The 2020 ICPC Asia Shenyang Regional Programming Contest 题目大意: 一天内有H小时,每小时M分钟,时针分针以恒定速率旋转. 现在若时针 ...

  6. The 2020 ICPC Asia Yinchuan Regional Programming Contest

    The 2020 ICPC Asia Yinchuan Regional Programming Contest A 开三个vector数组存储x,y,z轴上的点,unique+erase去重 #in ...

  7. The 2019 ICPC Asia Shanghai Regional Contest

    The 2019 ICPC Asia Shanghai Regional Contest 题号 题目 知识点 A Mr. Panda and Dominoes B Prefix Code C Maze ...

  8. 2018 ICPC Asia Jakarta Regional Contest

    2018 ICPC Asia Jakarta Regional Contest 题号 题目 知识点 难度 A Edit Distance B Rotating Gear C Smart Thief D ...

  9. 【题目记录】——The 2021 ICPC Asia Jinan Regional Contest

    文章目录 C Optimal Strategy 组合数 H Game Coin K Search For Mafuyu 欧拉序列 题目集地址 The 2021 ICPC Asia Jinan Regi ...

最新文章

  1. IDEA中快捷键修改成和eclipse一样
  2. iOS进阶之架构设计MVC(1)
  3. spark学习(二)
  4. javascript中parentNode,childNodes,children的应用详解
  5. 豪鹫闲谈--什么因素影响了我们的工资
  6. [Android系列—] 1. Android 开发环境搭建与Hello World
  7. 【机器学习】--谱聚类从初始到应用
  8. 使用phpQuery 抓取HTML 页面内容
  9. windows11没有ie浏览器解决办法
  10. 阿里云迁移工具推荐最佳实践:Xen虚拟化迁移到阿里云
  11. 看我如何快速拿下整个C段主机权限
  12. 仿今日头条后台管理系统(三)
  13. lol s7 linux,LOLs7 赛季季末冲刺挑战赛参加地址介绍
  14. 可视化随笔 阶梯图
  15. 她说晚上加班,被一段python代码无情戳穿
  16. 【从菜鸟到高手】日期格式化
  17. Redhat防火墙端口设置
  18. 中小型企业erp管理系统
  19. 关于fanuc机器人软件的使用
  20. There is no getter for property named 'DEPARTMENT_ID' in 'class com.sccy.hr.model.RewardsPunishment'

热门文章

  1. ajax上传文件 获取失败,Ajax上传文件/照片时报错TypeError :Illegal invocation的解决方法...
  2. windows制作定时关机脚本_自动关机、自动打开程序… 让Windows自动执行任何操作...
  3. apt-get 更新指定软件_GrandPerspective for mac(磁盘管理软件)
  4. mybatis mysql usegeneratedkeys_mybatis中useGeneratedKeys用法--插入数据库后获取主键值
  5. deb包如何改支持12系统_对一个deb包的解压、修改、重新打包全过程方法
  6. 软件构造学习笔记-实验3
  7. 荣耀智慧屏功能曝光 首发华为鸿蒙OS,荣耀智慧屏功能曝光:首发华为鸿蒙OS,全场景智慧体验...
  8. [JavaWeb-Servlet]概述与快速入门
  9. [JavaWeb-HTML]HTML标签_语义化标签
  10. [Qt入门] QPushButton创建