题目大意:n个数字,m次操作,支持修改一个数字和查询一个区间内每种数字最大出现位置减最小出现位置的和。(n,m<=100,000)

做法:把每个数字表示成二维平面上的点,第一维是在数组中的位置,第二维是在数组中前一个相同数字的位置,权值为这两个位置的差,询问等同于求矩形和,修改时会影响自己和相邻的相同数字,每种开一个set维护即可。矩形和可以用cdq分治,不容易被卡空间。

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<queue>
#include<map>
#include<set>
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
#define MN 100000
#define N 131072
set<int> s[MN+];
int a[MN+],ls[MN+],wn,qn,pn;
long long ans[MN+],t[N*+];
struct work{int t,a,b,c;}w[MN*+];
struct P{int t,a,b,c,d;}p[MN*+];
bool cmp(const P&a,const P&b){return a.a==b.a?a.t<b.t:a.a<b.a;}
void add(int k,int x){for(k+=N;k;k>>=)t[k]+=x;}
long long query(int l,int r)
{
long long res=;
for(l+=N-,r+=N+;l^r^;l>>=,r>>=)
{
if(~l&)res+=t[l+];
if( r&)res+=t[r-];
}
return res;
}
void solve(int l,int r)
{
int mid=l+r>>,i;
if(l<r)solve(l,mid),solve(mid+,r);
for(pn=,i=l;i<=mid;++i)if(w[i].t<)p[++pn]=(P){,w[i].a,w[i].b,w[i].c,};
for(;i<=r;++i)if(w[i].t>)p[++pn]=(P){,w[i].a-,w[i].a,w[i].b,w[i].c},
p[++pn]=(P){,w[i].b,w[i].a,w[i].b,w[i].c};
sort(p+,p+pn+,cmp);
for(i=;i<=pn;++i)
{
if(p[i].t==)add(p[i].b,p[i].c);
if(p[i].t==)ans[p[i].d]-=query(p[i].b,p[i].c);
if(p[i].t==)ans[p[i].d]+=query(p[i].b,p[i].c);
}
for(i=;i<=pn;++i)if(p[i].t==)add(p[i].b,-p[i].c);
}
int main()
{
int n,m,i,t,x,y;
n=read();m=read();
for(i=;i<=n;s[a[i]].insert(ls[a[i]]=i),++i)
if(ls[a[i]=read()])w[++wn]=(work){,i,ls[a[i]],i-ls[a[i]]};
for(i=;i<=m;++i)
{
t=read();x=read();y=read();
if(t==)
{
set<int>::iterator i=s[a[x]].find(x),j=i,k=i;++k;
if(i!=s[a[x]].begin())
{
--j;w[++wn]=(work){,x,*j,*j-x};
if(k!=s[a[x]].end())w[++wn]=(work){,*k,*j,*k-*j};
}
if(k!=s[a[x]].end())w[++wn]=(work){,*k,x,x-*k};
s[a[x]].erase(i);
s[a[x]=y].insert(x);
i=j=k=s[y].find(x);++k;
if(i!=s[y].begin())
{
--j;w[++wn]=(work){,x,*j,x-*j};
if(k!=s[y].end())w[++wn]=(work){,*k,*j,*j-*k};
}
if(k!=s[y].end())w[++wn]=(work){,*k,x,*k-x};
}
else w[++wn]=(work){,x,y,++qn};
}
solve(,wn);
for(i=;i<=qn;++i)printf("%I64d\n",ans[i]);
}

[Codeforces]848C - Goodbye Souvenir的更多相关文章

  1. Codeforces 848C Goodbye Souvenir(CDQ 分治)

    题面传送门 考虑记录每个点的前驱 \(pre_x\),显然答案为 \(\sum\limits_{i=l}^{r} i-pre_i (pre_i \geq l)\) 我们建立一个平面直角坐标系,\(x\ ...

  2. Codeforces 848C Goodbye Souvenir [CDQ分治,二维数点]

    洛谷 Codeforces 这题我写了四种做法-- 思路 不管做法怎样,思路都是一样的. 好吧,其实不一样,有细微的差别. 第一种 考虑位置\(x\)对区间\([l,r]\)有\(\pm x\)的贡献 ...

  3. [Codeforces]849E Goodbye Souvenir

    又是一道比较新的模板题吧,即使是在Codeforces上小C还是贴了出来. Description 给定一个长度为n的序列a1~an,每个元素代表一种颜色.m次操作,每次操作为两种中的一种: 1 p ...

  4. Codeforces 848C (cdq分治)

    Codeforces 848C Goodbye Souvenir Problem : 给一个长度为n的序列,有q个询问.一种询问是修改某个位置的数,另一种询问是询问一段区间,对于每一种值出现的最右端点 ...

  5. 【Codeforces 848C】Goodbye Souvenir

    Codeforces 848 C 题意:给\(n\)个数,\(m\)个询问,每一个询问有以下类型: 1 p x:将第p位改成x. 2 l r:求出\([l,r]\)区间中每一个出现的数的最后一次出现位 ...

  6. CF848C:Goodbye Souvenir(CDQ分治)

    Description 给定长度为$n$的数组, 定义数字$X$在$[l,r]$内的值为数字$X$在$[l,r]$内最后一次出现位置的下标减去第一次出现位置的下标给定$m$次询问, 每次询问有三个整数 ...

  7. codeforces 848c - two TVs

    2017-08-22 15:42:44 writer:pprp 参考:http://blog.csdn.net/qq_37497322/article/details/77463376#comment ...

  8. 【Codeforces Round 431 (Div. 2) A B C D E五个题】

    先给出比赛地址啦,感觉这场比赛思维考察非常灵活而美妙. A. Odds and Ends ·述大意:      输入n(n<=100)表示长度为n的序列,接下来输入这个序列.询问是否可以将序列划 ...

  9. Codeforces Goodbye 2018

    Goodbye 2018 可能是我太菜考试的时候出不了$E$ 可能是我太菜考试的时候调不出$F$ 所以转化为手速场之后手速还上不去.jpg A 模拟题意... #include <cstdio& ...

随机推荐

  1. c语言字符类型作业

    一.PTA实验作业 题目1:7-2 统计一行文本的单词个数 1. 本题PTA提交列表 2. 设计思路 1.定义整形变量i=0,count=0,flag. 2.定义数组str[999] 3.输入str[ ...

  2. 实验MyOD

    实验MyOD 编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 提交测试代码和运行结果截图,加上学号水印,提交码云代码链接. 代码如下: (刚开始 ...

  3. 201621123040《Java程序设计》第十周学习总结

    1.本周学习总结 2.书面作业 2.1常用异常 2.1.1自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避免? 算术异常ArithmeticException(除数为0的情况) 类 ...

  4. Java课程设计报告——学生成绩管理系统

    一.需求分析 1.数据存储在数据库和文件中 2.分为"教师"模块和"学生"模块. 3.学生模块提供登陆功能,登陆成功后可查询数学.Java.体育成绩 (学生学号 ...

  5. Tornado websocket应用

    应用场景 WebSocket 的特点如下 适合服务器主动推送的场景(好友上线,即时聊天信息,火灾警告,股票涨停等) 相对于Ajax和Long poll等轮询技术,它更高效,不耗费网络带宽和计算资源 它 ...

  6. Angular组件——组件生命周期(一)

    组件声明周期以及angular的变化发现机制 红色方法只执行一次. 变更检测执行的绿色方法和和组件初始化阶段执行的绿色方法是一个方法. 总共9个方法. 每个钩子都是@angular/core库里定义的 ...

  7. spring-oauth-server实践:access_token的有效期分析

    1.access_token有效期检查 用expiration和new Date()比较!!!!!! 分析目标-->expiration什么时候设置,设置规则如何配置!!!!!!! 2.acce ...

  8. Spring Security 入门(1-3-2)Spring Security - http元素 - intercept-url配置

    http元素下可以配置登录页面,也可以配置 url 拦截. 1.直接配置拦截url和对应的访问权限 <security:http use-expressions="false" ...

  9. CTF中常见密码题解密网站总结

    0x00.综合 网站中包含大多编码的解码. http://web2hack.org/xssee/ https://www.sojson.com/ http://web.chacuo.net/ 0x01 ...

  10. 两款不同应用场景的Wpf分页控件

    简介 今天给大家分享两个Wpf分页控件,本篇博客主要介绍一些实现思路和使用方法,具体实现和应用代码请参考文末的Demo链接 废话不多说,先看一下效果~ (两款控件显示效果是一样的) 实现思路 一款控件 ...