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. iOS界面设计之基础控件的学习 --- UITextField

    学习iOS界面设计也有段时间了,每次写到一些基础控件(如:UILable . UITextField)的时候就深觉应该总结一个函数来实现这些基础控件的属性设置,所以下面就是我对UITextField的 ...

  2. 条形码生成库 BarcodeLib

    官方介绍 在ASP.NET,Windows,Reporting Service,Crystal Reports 和 RDLC Reports应用程序中轻松生成条形码 生成准确的条形码图像,并可以保存为 ...

  3. 编写shell时,遇到let: not found错误及解决办法

    #!/bin/bashi=1sum=0while [ $i -le 100 ]do  let sum=sum+$i  let i++ done 在写一个简单的循环脚本时,报错 let: not fou ...

  4. Linux下编译程序时,经常会遇到“undefined reference to XXX” 报错,

    Linux下编译程序时,经常会遇到“undefined reference to XXX” 报错, 这里总结一些可能的原因和解决方案,给需要的朋友: 说道undefined reference err ...

  5. hdu-题目1159:Common Subsequence

    http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Java/Oth ...

  6. Spring注解原理

    一.注解的基本概念和原理及其简单实用 注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解 ...

  7. FZU2127_养鸡场

    题目的意思为要你求出满足三边范围条件且周长为n的三角形的数目. 其实做法是直接枚举最短边,然后就可以知道第二条边的取值范围,同时根据给定的范围缩小范围. 同时根据第二条边的范围推出第三条边的范围,再次 ...

  8. java finally 与return

    finally之外的语句块有return,finally语句块没有return:该语句块的返回值被固定下来,等fianlly执行完后返回给调用者 finally语句块与其他语句块同时有return:返 ...

  9. 秒杀多线程第二篇 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别(续)

    由于原作者主要写window上的线程,而我主要学习android,所以本文将分析android方面多线程. 1.Thread: public void Thread1(){ Thread a = ne ...

  10. [四]SpringBoot 之 捕捉全局异常

    在class注解上@ControllerAdvice, 在方法上注解上@ExceptionHandler(value = Exception.class),具体代码如下: package me.shi ...