hdu 3874 线段树 离线查询
2016-05-26 01:21
483 查看
要求一个区间所有数之和 求和时要去重
离线查询 先把所有查询离线 然后按照右端点排序 每次保证加入后一个数的时候线段树中没有和他重复的 如果重复就把前一个删掉 这样由于之前排序过 保证不会漏解
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
#define ll __int64
const int N=50010;
const int M=200010;
struct node
{
int l,r,i;
}q[M];
int n,a
,vis[1000010];
ll sum[N<<2],ans[M];
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int p,int add,int l,int r,int rt)
{
if(l==r){
sum[rt]+=add;return;
}
int mid=l+r>>1;
if(p<=mid) update(p,add,lson);
else update(p,add,rson);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return sum[rt];
int mid=l+r>>1;
ll ans=0;
if(L<=mid) ans+=query(L,R,lson);
if(R>mid) ans+=query(L,R,rson);
return ans;
}
bool cmp(node a,node b)
{
return a.r<b.r;
}
int main()
{//freopen("C:\\Users\\Administrator\\Desktop\\input.txt","r",stdin);
int T,Q,i;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
memset(sum,0,sizeof(sum));
scanf("%d",&Q);
for(i=1;i<=Q;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].i=i;
}
sort(q+1,q+Q+1,cmp);
memset(vis,0,sizeof(vis));
int p=1;
for(i=1;i<=Q;i++){
while(p<=q[i].r){
if(vis[a[p]])update(vis[a[p]],-a[p],1,n,1);
vis[a[p]]=p;
update(p,a[p],1,n,1);
p++;
}
ans[q[i].i]=query(q[i].l,q[i].r,1,n,1);
}
for(i=1;i<=Q;i++) printf("%I64d\n",ans[i]);
}
return 0;
}
离线查询 先把所有查询离线 然后按照右端点排序 每次保证加入后一个数的时候线段树中没有和他重复的 如果重复就把前一个删掉 这样由于之前排序过 保证不会漏解
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
#define ll __int64
const int N=50010;
const int M=200010;
struct node
{
int l,r,i;
}q[M];
int n,a
,vis[1000010];
ll sum[N<<2],ans[M];
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int p,int add,int l,int r,int rt)
{
if(l==r){
sum[rt]+=add;return;
}
int mid=l+r>>1;
if(p<=mid) update(p,add,lson);
else update(p,add,rson);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)return sum[rt];
int mid=l+r>>1;
ll ans=0;
if(L<=mid) ans+=query(L,R,lson);
if(R>mid) ans+=query(L,R,rson);
return ans;
}
bool cmp(node a,node b)
{
return a.r<b.r;
}
int main()
{//freopen("C:\\Users\\Administrator\\Desktop\\input.txt","r",stdin);
int T,Q,i;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
memset(sum,0,sizeof(sum));
scanf("%d",&Q);
for(i=1;i<=Q;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].i=i;
}
sort(q+1,q+Q+1,cmp);
memset(vis,0,sizeof(vis));
int p=1;
for(i=1;i<=Q;i++){
while(p<=q[i].r){
if(vis[a[p]])update(vis[a[p]],-a[p],1,n,1);
vis[a[p]]=p;
update(p,a[p],1,n,1);
p++;
}
ans[q[i].i]=query(q[i].l,q[i].r,1,n,1);
}
for(i=1;i<=Q;i++) printf("%I64d\n",ans[i]);
}
return 0;
}
相关文章推荐
- Java序列化与反序列化
- LeetCode 147. Insertion Sort List(插入有序链表)
- HDOJ/HDU 1073 Online Judge(字符串处理~)
- HDOJ/HDU 1073 Online Judge(字符串处理~)
- hdu 2852 线段树 单点更新
- Android N画中画模式
- LeetCode 148. Sort List(链表排序)
- win8.1安装软件报错-2503和2502
- iOS多线程编程及GCD简介
- 量化分析:把Tushare数据源,规整成PyalgoTrade所需格式
- php array_filter过滤数组为空值
- Hibernate错误
- C语言中访问结构体成员时 点 . 和 箭头 -> 的区别
- Leetcode no. 257
- POJ 1008 (模拟)
- IntentFilter过滤规则
- Navicat
- Linux 网络 I/O 模型简介(图文)
- LeetCode 149. Max Points on a Line(直线上的点)
- 通过srvctl add命令添加database信息到srvctl管理器