CF 848C
听说,一个好的oier是题目喂出来的。
题目
给定长度为n的数组, 定义数字X在[l,r]内的值为数字X在[l,r]内最后一次出现位置的下标减去第一次出现位置的下标
给定m次询问, 每次询问有三个整数a,b,c询问规则如下:
当a=1时, 将数组内第b个元素更改为c
当a=2时, 求区间[b,c]所有数字的值的和
解题思路
不难想到对于每个点,记录上一个权值和他相同的点的下标(不妨称之为前驱),设他的权值为这两个下标之差。
于是可以发现 [l,r] 的权值可以基本表示为[l,r]内所有点的权值和。
但我们很快发现,我们多加了一些。
而后修正为[l,r]内所有前驱也在[l,r]内的点的权值和。
然后看着就很像查询二维平面上一个矩形的和了。
CDQ分治即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int sz=7e5+527;
struct hh{
int x,y,t,val;
}tmp[sz],q[sz];
int n,m;
int tot,cnt;
int type,x,y;
ll a[sz],f[sz];
ll ans[sz];
set<int>S[sz];
set<int>::iterator it;
int head[sz],lst[sz];
void update(int x,int sum){
for(;x<=n+1;x+=(x&(-x))) f[x]+=sum;
}
ll query(int x){
ll ret=0;
for(;x;x-=x&(-x)) ret+=f[x];
return ret;
}
void cdq(int l,int r){
if(l==r) return;
int mid=(l+r)>>1;
cdq(l,mid),cdq(mid+1,r);
int i=l,j=mid+1,k=l-1;
while(i<=mid||j<=r){
if(j>r || i<=mid && (q[i].x<q[j].x || q[i].x==q[j].x &&q[i].t<q[j].t)){
if(!q[i].t) update(q[i].y,q[i].val);
tmp[++k]=q[i];
i++;
}
else{
if(q[j].t){
int num=abs(q[j].val);
if(q[j].val>0) ans[num]+=query(q[j].y);
else ans[num]-=query(q[j].y);
}
tmp[++k]=q[j];
j++;
}
}
for(int i=l;i<=mid;i++) if(!q[i].t) update(q[i].y,-q[i].val);
for(int i=l;i<=r;i++) q[i]=tmp[i];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
S[a[i]].insert(i);
lst[i]=head[a[i]],head[a[i]]=i;
q[++tot]=(hh){i,lst[i],0,i-lst[i]};
}
for (int i=1; i<=m; ++i){
scanf("%d%d%d",&type,&x,&y);
if (type==1){
int p1=0,n1=0;//前驱 后继
it=S[a[x]].find(x);
if (it!=S[a[x]].begin()) --it, p1=*it, ++it;
if ((++it)!=S[a[x]].end()) n1=*it; --it;
S[a[x]].erase(*it); q[++tot]=(hh){x,lst[x],0,lst[x]-x};
if(n1){
q[++tot]=(hh){n1,lst[n1],0,lst[n1]-n1};
lst[n1]=p1;
q[++tot]=(hh){n1,lst[n1],0,n1-lst[n1]};
}
int p2=0,n2=0;
a[x]=y; S[a[x]].insert(x);
it=S[a[x]].find(x);
if (it!=S[a[x]].begin()) --it, p2=*it, ++it;
if ((++it)!=S[a[x]].end()) n2=*it; --it;
lst[x]=p2; q[++tot]=(hh){x,lst[x],0,x-lst[x]};
if (n2){
q[++tot]=(hh){n2,lst[n2],0,lst[n2]-n2};
lst[n2]=x;
q[++tot]=(hh){n2,lst[n2],0,n2-lst[n2]};
}
}
else{
++cnt;
q[++tot]=(hh){x-1,x-1,1,cnt};
q[++tot]=(hh){y,y,1,cnt};
q[++tot]=(hh){x-1,y,1,-cnt};
q[++tot]=(hh){y,x-1,1,-cnt};
}
}
for (int i=1; i<=tot; ++i) q[i].x++, q[i].y++;
cdq(1,tot);
for(int i=1;i<=cnt;i++) printf("%lld\n",ans[i]);
}
CF 848C的更多相关文章
- ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'
凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- cf Round 613
A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...
- ARC下OC对象和CF对象之间的桥接(bridge)
在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...
- [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现
1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...
- CF memsql Start[c]UP 2.0 A
CF memsql Start[c]UP 2.0 A A. Golden System time limit per test 1 second memory limit per test 256 m ...
- CF memsql Start[c]UP 2.0 B
CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...
- CF #376 (Div. 2) C. dfs
1.CF #376 (Div. 2) C. Socks dfs 2.题意:给袜子上色,使n天左右脚袜子都同样颜色. 3.总结:一开始用链表存图,一直TLE test 6 (1)如果需 ...
- CF #375 (Div. 2) D. bfs
1.CF #375 (Div. 2) D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...
随机推荐
- 02.vs插件 获取项目和解决方案路径
获取项目 解决方案路径 /// <summary> /// 获取并设置项目和解决方案绝对路径 /// </summary> /// <returns></re ...
- 数据交互 axios 的使用
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. ##Axios npm version build status code coverage npm ...
- eclipse memory analyzer对系统内存溢出堆文件解析0(转)
前言 在平时工作过程中,有时会遇到OutOfMemoryError,我们知道遇到Error一般表明程序存在着严重问题,可能是灾难性的.所以找出是什么原因造成OutOfMemoryError非常重要.现 ...
- java RSA验签
这几天在跟一个php的小哥哥联调接口,遇到了一些问题记录下来, 直接上代码吧,亲测有效 import org.slf4j.Logger; import org.slf4j.LoggerFactory; ...
- Python-pip更改国内源
windows方式: 1.打开任意文件夹,在上方地址栏中输入%appdata% 2.在此目录里新建文件夹pip 3.在pip文件夹里新建文件名:pip.ini 4.把以下内容复制到pip.ini中,保 ...
- C++【stack/queue】用法和例子
Stack的常用基本操作: s.push() // 压栈 s.emplace() // 插入,相当于push(目前掌握的唯一区别是emplace可以自行调用构造函数,push不行) s.empty() ...
- springboot思维导图
- Leetcode944. Delete Columns to Make Sorted删列造序
给定由 N 个小写字母字符串组成的数组 A,其中每个字符串长度相等. 选取一个删除索引序列,对于 A 中的每个字符串,删除对应每个索引处的字符. 所余下的字符串行从上往下读形成列. 比如,有 A = ...
- 在Spring框架中获取连接池的四种方式
1:DBCP数据源 DBCP类包位于 <SPRING_HOME>/lib/jakarta-commons/commons-dbcp.jar,DBCP是一个依赖Jakarta commons ...
- linux命令统计文件中某个字符串出现的次数
1.使用grep linux grep命令在我的随笔linux分类里有过简单的介绍,这里就只简单的介绍下使用grep命令统计某个文件这某个字符串出现的次数,首先介绍grep命令的几个参数,详细参数请自 ...