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个湖,总要填掉多 ...
随机推荐
- css正則匹配、模糊匹配
//所有class包含font-red的p标签 p[class~="font-red"] {color: red;} [abc^="def"] 选择 abc 属 ...
- git 命令行(三)-删除文件
在Git中,删除也是一个修改操作,我们实战一下,有一个多余的文件:src/common/Util2.js 我们需要删除这个文件, 一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用 rm命令 ...
- VS2012 TFS 解决计算机改名无法连接TFS的问题
闲着没事改了下计算机名字,结果造成TFS无法连接. 报错讯息如下: ---------------------------Microsoft Visual Studio-------------- ...
- Installer - win10安装及卸载SQL Server2008数据库
一.数据库安装环境 操作系统:win10 SQL server:SQL server 2008 R2 二.全新数据库安装 1.安装扩展文件 双击安装文件,弹出如下窗体: ...
- 左神算法进阶班5_4设计可以变更的缓存结构(LRU)
[题目] 设计一种缓存结构,该结构在构造时确定大小,假设大小为K,并有两个功能: set(key, value):将记录(key, value)插入该结构. get(key):返回key对应的valu ...
- java线程池的使用学习
目录 1. 线程池的创建 2. 线程池的运行规则 3. 线程池的关闭 4. 线程池的使用场合 5. 线程池大小的设置 6 实现举例 1. 线程池的创建 线程池的创建使用ThreadPoolExecut ...
- 操作系统命令工具Util
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- Chapter 3 树与二叉树
Chapter 3 树与二叉树 1- 二叉树 主要性质: 1 叶子结点数 = 度为2的结点数 + 1 2 二叉树第i层上最多有 (i≥1)个结点 3 深度为k的二叉树最多有 个结点 ...
- 使用 MongoDB shell访问MongoDB
- [jeecms]获取父栏目下的子栏目名称
[@cms_channel_list parentId='父栏目id'] [#list tag_list as c] <a href="${c.url}">${c.na ...