Melancholy

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

  DX3906星系,Melancholy星上,我在勘测这里的地质情况。
  我把这些天来已探测到的区域分为N组,并用二元组(D,V)对每一组进行标记:其中D为区域的相对距离,V为内部地质元素的相对丰富程度
  在我的日程安排表上有Q项指派的计划。
  每项计划的形式是类似的,都是“对相对距离D在[L,R]之间的区域进行进一步的勘测,并在其中有次序地挑出K块区域的样本进行研究。”采集这K块的样品 后,接下来在实验中,它们的研究价值即为这K块区域地质相对丰富程度V的乘积。
  我对这Q项计划都进行了评估:一项计划的评估值P为所有可能选取情况的研究价值之和。
  但是由于仪器的原因,在一次勘测中,这其中V最小的区域永远不会被选取。
  现在我只想知道这Q项计划的评估值对2^32取模后的值,特殊地,如果没有K块区域可供选择, 评估值为0。

Input

  第一行给出两个整数,区域数N与计划数Q。
  第二行给出N个整数,代表每一块区域的相对距离D。
  第三行给出N个整数,代表每一块区域的内部地质元素的相对丰富程度V。
  接下来的Q行,每一行3个整数,代表相对距离的限制L,R,以及选取的块数K。

Output

  输出包括Q行,每一行一个整数,代表这项计划的评估值对2^32取模后的值。

Sample Input

  5 3
  5 4 7 2 6
  1 4 5 3 2
  6 7 1
  2 6 2
  1 8 3

Sample Output

  5
  52
  924

  

HINT

  

Main idea

  查询D在[L, R]中的元素,去掉最小的L值之后,任意k几个相乘的和。

Solution

  首先,我们可以按照D排序一下,然后调出D在[L,R]的元素,显然是连续的一段

  然后我们再记录一下最小值L,以及最小值L所在的位置。这样在线段树上区间查询一下,就可以得到最小值的pos

  那么我们就将询问化成了,查询两个区间的信息并且合并

  问题在于如何合并

  我们对于线段树上的每个节点,记录一下val[i]表示选了i乘起来的和

  那么两个区间合并起来时,val[i] = ΣA.val[j] * B.val[i - j],根据乘法分配律可以看出。

  比如我们左区间选了2个的答案形如:x1·x2 + y1·y2右区间选了1个的答案形如:z1 + z2

  那么合并之后的区间 选了3个答案形如:x1·x2·z1 + x1·x2·z2 + y1·y2·z2+ y1·y2·z2,显然就是两个乘起来,并且不漏状态

  这样就可以得到答案啦。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef unsigned int u32; const int ONE = ;
const int MOD = 1e9 + ;
const u32 INF = 4294967295u; int n, Q;
int k;
struct point
{
u32 d, v;
}a[ONE], L, R;
bool cmp(const point &a, const point &b) {return a.d < b.d;} struct power
{
u32 val[];
friend power operator +(power a, power b)
{
power c;
for(int i = ; i <= ; i++) c.val[i] = a.val[i] + b.val[i];
for(int i = ; i <= ; i++)
for(int j = ; j < i; j++)
c.val[i] += a.val[j] * b.val[i - j];
return c;
}
}Node[ONE], A[], Ans; struct Min
{
u32 val, pos;
friend Min operator +(Min a, Min b)
{
Min c = (Min){INF, };
if(a.val < c.val) c = a;
if(b.val < c.val) c = b;
return c;
}
}Val[ONE], res_min; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} namespace Seg
{
void Build(int i, int l, int r)
{
Val[i] = (Min){INF, };
for(int j = ; j <= ; j++) Node[i].val[j] = ;
if(l == r)
{
Node[i].val[] = a[l].v;
Val[i] = (Min){a[l].v, l};
return;
}
int mid = l + r >> ;
Build(i << , l, mid); Build(i << | , mid + , r);
Node[i] = Node[i << ] + Node[i << | ];
Val[i] = Val[i << ] + Val[i << | ];
} void Find(int i, int l, int r, int L, int R)
{
if(L > R) return;
if(L <= l && r <= R)
{
res_min = res_min + Val[i];
return;
}
int mid = l + r >> ;
if(L <= mid) Find(i << , l, mid, L, R);
if(mid + <= R) Find(i << | , mid + , r, L, R);
} void Query(int i, int l, int r, int L, int R, int opt)
{
if(L > R) return;
if(L <= l && r <= R)
{
A[opt] = A[opt] + Node[i];
return;
}
int mid = l + r >> ;
if(L <= mid) Query(i << , l, mid, L, R, opt);
if(mid + <= R) Query(i << | , mid + , r, L, R, opt);
}
} void Deal(int k)
{
int Left = lower_bound(a + , a + n + , L, cmp) - a;
int Right = upper_bound(a + , a + n + , R, cmp) - a - ;
if(Left >= Right) {printf("0\n"); return;} res_min = (Min){INF, };
Seg::Find(, , n, Left, Right); for(int i = ; i <= ; i++) A[].val[i] = A[].val[i] = ;
Seg::Query(, , n, Left, res_min.pos - , );
Seg::Query(, , n, res_min.pos + , Right, ); Ans = A[] + A[];
for(u32 i = ; i <= k; i++) Ans.val[k] *= i;
printf("%u\n", Ans.val[k]);
} int main()
{
n = get(); Q = get();
for(int i = ; i <= n; i++) a[i].d = get();
for(int i = ; i <= n; i++) a[i].v = get();
sort(a + , a + n + , cmp); Seg::Build(, , n); while(Q--)
{
L.d = get(), R.d = get(), k = get();
Deal(k);
}
}

【Foreign】Melancholy [线段树]的更多相关文章

  1. 【Foreign】数据结构C [线段树]

    数据结构C Time Limit: 20 Sec  Memory Limit: 512 MB Description Input Output Sample Input Sample Output H ...

  2. 【Foreign】Weed [线段树]

    Weed Time Limit: 20 Sec  Memory Limit: 512 MB Description 从前有个栈,一开始是空的. 你写下了 m 个操作,每个操作形如 k v : 若 k ...

  3. 【Foreign】划分序列 [线段树][DP]

    划分序列 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 9 4 ...

  4. 【Foreign】染色 [LCT][线段树]

    染色 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output Sample Input 13 0 1 0 2 1 11 1 ...

  5. 【Foreign】阅读 [线段树][DP]

    阅读 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 0 10 4 10 2 3 10 8 ...

  6. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  7. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  8. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  9. codevs 1080 线段树点修改

    先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...

随机推荐

  1. lintcode-397-最长上升连续子序列

    397-最长上升连续子序列 给定一个整数数组(下标从 0 到 n-1, n 表示整个数组的规模),请找出该数组中的最长上升连续子序列.(最长上升连续子序列可以定义为从右到左或从左到右的序列.) 注意事 ...

  2. C#高级编程 (第六版) 学习 第三章:对象和类型

    第三章 对象和类型 1,类和结构 类存储在托管堆上 结构存储在堆栈上   2,类成员 类中的数据和函数称为类成员 数据成员 数据成员包括了字段.常量和事件   函数成员 方法:与某个类相关的函数,可以 ...

  3. Java & hashCode作用

    首先,想要明白hashCode的作用,你必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set.你知道它们的区别吗?前者集合内的元素 ...

  4. Docker 技术 介绍

    https://github.com/docker/docker 实现用户空间隔离的技术:名称空间(NameSpace),CGroup(控制组) 什么是NameSpace::简单的理解就是,每一个虚拟 ...

  5. 1014 我的C语言文法定义与C程序推导过程

    程序> -> <外部声明> | <程序> <外部声明> <外部声明> -> <函数定义> | <声明> < ...

  6. 1."问吧APP"客户需求调查分析

    产品名称:问吧 产品功能:实时提问回答和搜索 开发原因:任何人都会遇到问题,网上虽然有很多回答,但是互联网的信息错综复杂,开发这个APP就是为了让网络求助更加的合理有效,清除网络上的垃圾信息. 为知大 ...

  7. 【BioCode】删除未算出PSSM与SS的蛋白质序列

    代码说明: 由于一些原因(氨基酸序列过长),没有算出PSSM与SS,按照整理出来的未算出特征的文件,删除原来的蛋白质序列: 需删除的氨基酸文件732.txt(共732条氨基酸): 删除前 氨基酸共25 ...

  8. Mac下Java JNI 调C

    简介 JNI的实现步骤如下: 编写带有native声明的方法的Java类 使用javac命令编译编写的Java类 使用java -jni className 来生成后缀名为.h的头文件 使用其他语言( ...

  9. v-for & duplicate key bug

    v-for & duplicate key bug vue warn & v-for & duplicate key bug <span class="audi ...

  10. Android四大组件之Intent

    Intent不是android几大组件框架,但是确实是android 各大组件之间沟通的桥梁. 尤其Intent对于activity有很大的关系. 一下是我个人对task以及backstack的总结.