题意:

  给一个数列,一些询问,问你$[l,r]$之间不同的数字之和

题解:

  11年多校的题,现在属于"人尽皆知傻逼题"

  核心思想在于:  对于一个询问$[x,R]$ 无论$x$是什么,整个数列中,对于答案有贡献的,只有每种数字中,$R$左边最近的一个

  对于数列$1,1,2,2,3,3,4,4,1,1,2,2,4,3,4,5,5,P...$和

           $0,0,0,0,0,0,0,0,0,1,0,2,0,3,4,0,5,P...$ 只要右边界保持在P-1,询问结果是等价的

具体操作就是,存储询问,按R排序,依次处理,删除当前询问R之前所有的,只保存最后一个

用线段树,树状数组都行,做单点修改区间查询就行..

bit

#include <bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pp pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
#define per(ii,a,b) for(int ii=a;ii>=b;ii--)
using namespace std;
const int maxn=1e6+10;
const int maxm=1e6*4+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
#define lb(x) x&-x
ll bit[maxn],num[maxn];
void update(int pos,int x){
while(pos<=n){
bit[pos]+=x,pos+=lb(pos);
}
}
ll sum(int pos){
ll ans=0;
while(pos){
ans+=bit[pos],pos-=lb(pos);
}
return ans;
}
ll query(int a,int b){
return sum(b)-sum(a-1);
}
struct node2 {
int l,r,id;
}ask[maxn];
int cmp(node2 a,node2 b){
return a.r<b.r;
}
map<ll,int>pos;
ll ans[maxn];
int main(){
//#define test
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
scanf("%d",&casn);
while(casn--){
scanf("%d",&n);
rep(i,1,n) bit[i]=0;
for(int i=1;i<=n;i++){
scanf("%lld",num+i);
update(i,num[i]);
}
pos.clear();
scanf("%d",&k);
int a,b;
for(int i=1;i<=k;i++){
scanf("%d%d",&a,&b);
ask[i]=(node2){a,b,i};
}
sort(ask+1,ask+1+k,cmp);
int r=1;
for(int i=1;i<=k;i++){
while(r<=ask[i].r){
if(pos[num[r]]){
update(pos[num[r]],-num[r]);
}
pos[num[r]]=r;
r++;
}
ans[ask[i].id]=query(ask[i].l,ask[i].r);
}
for(int i=1;i<=k;i++){
printf("%lld\n",ans[i]);
}
} #ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

线段树

#include <bits/stdc++.h>
#define ll long long
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pp pair<int,int>
#define rep(ii,a,b) for(int ii=a;ii<=b;ii++)
#define per(ii,a,b) for(int ii=a;ii>=b;ii--)
using namespace std;
const int maxn=1e5+10;
const int maxm=1e6+10;
const int INF=0x3f3f3f3f;
int casn,n,m,k;
#define nd lst[now]
struct node {
int l,r;ll sum;
}lst[maxm];
ll num[maxn];
void maketree(int s=1,int t=n,int now=1){
nd=(node){s,t,num[s]};
if(s==t) return ;
maketree(s,(s+t)>>1,now<<1);
maketree(((s+t)>>1)+1,t,now<<1|1);
nd.sum=lst[now<<1].sum+lst[now<<1|1].sum;
}
inline void pushup(int now) {
nd.sum=lst[now<<1].sum+lst[now<<1|1].sum;
}
void update(int pos,int x,int now=1){
if(pos<nd.l||pos>nd.r) return ;
if(nd.r==nd.l){
nd.sum=x;
return;
}
update(pos,x,now<<1);
update(pos,x,now<<1|1);
pushup(now);
}
ll query(int s,int t,int now=1){
if(s>nd.r||t<nd.l) return 0;
if(s<=nd.l&&t>=nd.r) return nd.sum;
return query(s,t,now<<1)+query(s,t,now<<1|1);
}
struct node2 {
int l,r,id;
}ask[maxn];
int cmp(node2 a,node2 b){
return a.r<b.r;
}
map<ll,int>pos;
ll ans[maxn];
int main(){
#define test123
#ifdef test
freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endif
scanf("%d",&casn);
while(casn--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",num+i);
}
pos.clear();
maketree();
scanf("%d",&k);
int a,b;
for(int i=1;i<=k;i++){
scanf("%d%d",&a,&b);
ask[i]=(node2){a,b,i};
}
sort(ask+1,ask+1+k,cmp);
int r=1;
for(int i=1;i<=k;i++){
while(r<=ask[i].r){
if(pos[num[r]]){
update(pos[num[r]],0);
}
pos[num[r]]=r;
r++;
}
ans[ask[i].id]=query(ask[i].l,ask[i].r);
}
for(int i=1;i<=k;i++){
printf("%lld\n",ans[i]);
}
} #ifdef test
fclose(stdin);fclose(stdout);system("out.txt");
#endif
return 0;
}

HDU 3333 Turing Tree 离线 线段树/树状数组 区间求和单点修改的更多相关文章

  1. hdu 3333 Turing Tree(线段树+离散化)

    刚看到是3xian大牛的题就让我菊花一紧,觉着这题肯定各种高端大气上档次,结果果然没让我失望. 刚开始我以为是一个普通的线段树区间求和,然后啪啪啪代码敲完测试没通过,才注意到这个求和是要去掉相同的值的 ...

  2. Hdu 5862 Counting Intersections(有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点+树状数组区间求和单点跟新)

    传送门:Hdu 5862 Counting Intersections 题意:有n条线段,每一条线段都是平行于x轴或者y轴,问有多少个交点 分析: 基本的操作流程是:先将所有的线段按照横树坐标x按小的 ...

  3. hdu 1116 敌兵布阵(树状数组区间求和)

    题意: 给出一行数字,然后可以修改其中第i个数字,并且可以询问第i至第j个数字的和(i <= j). 输入: 首行输入一个t,表示共有t组数据. 接下来每行首行输入一个整数n,表示共有n个数字. ...

  4. HDU 3333 Turing Tree 线段树+离线处理

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...

  5. hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)

    http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others)    ...

  6. 【poj2155】Matrix(二维树状数组区间更新+单点查询)

    Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...

  7. HDU 3333 Turing Tree (线段树)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)

    题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...

  9. HDU 3333 Turing Tree(离线树状数组)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

随机推荐

  1. 【leetcode70】【动态规划】 爬楼梯

    (1 pass 一维动态规划) 爬楼梯(easy) 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数 ...

  2. Vuex笔记

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 Vuex - 状态管理器,可以管理你的数据状态(类似于 React的 Redux) 一个 Vuex 应用的核心是 store(仓库,一个 ...

  3. javascript中var、let和const的区别

    在javascript中,var.let和const都可以用来声明变量,那么三者有什么区别呢?要回答这个问题,我们可以从先想想:三种不同的声明会影响变量的哪些方面?这些方面也就是变量的特性,那么变量有 ...

  4. [转载]SpringMVC解决跨域问题

    本文转载自  https://www.cnblogs.com/morethink/p/6525216.html SpringMVC解决跨域问题, 感谢作者! 有个朋友在写扇贝插件的时候遇到了跨域问题. ...

  5. sql parser

    最近在整理很多SQL代码, 需要分析出每个SQL的目标表和源表各有哪些, 网上没有找到工作具, 打算写个工具. Java调研结果:1. 商业组件包 sqlparser 有试用版组件, 限制SQL少于1 ...

  6. nginx接入let's encrypt

    按以下步骤: 一.放开443端口 我的是云服务器,默认没开放443端口,需要先在控制台放开 二.使用let’s encrypt 生成证书 执行以下命令: git clone https://githu ...

  7. android的android.intent.action.MAIN

    当我们使用Android Studio创建一个工程并生成一个Activity时,经常可以在清单文件中看到如下的代码 android.intent.action.MAIN:决定应用的入口Activity ...

  8. StarUML最新版2.8.1简单使用及代码生成

    StarUML(简称SU)是一款开放源码的UML开发工具,由韩国公司主导开发出来的,可以直接到StarUML网站下载. 在这里直接超链接:http://staruml.io/download SU是一 ...

  9. 【转】Parcelable, Serializable,Cloneable,copyProperties

    Copying ... https://blog.csdn.net/max2005/article/details/78325036 存在着三件事,整理如下 Parcelable, Serializa ...

  10. sqlserver导入execl

    一.找到导入导出的工具 找到安装目录 C:\Program Files\Microsoft SQL Server\100\DTS\Binn 里面的DTSWizard.exe 二.打开exe 然后下一步 ...