【NOIP2017模拟8.5】序列问题

Description

Input

输入文件名为seq.in。
首先输入n。
接下来输入n个数,描述序列 A。

Output

输出文件名为seq.out。
输出一行一个整数代表答案。

Sample Input

7
0 35 40 45 56 65 94

Sample Output

66636

Data Constraint

对于30%的数据,n<=5000
对于60%的数据,n<=50000
对于100%的数据,n<=500000,0<=A[i]<=10^9

ST加暴力枚举区间显然过不了,复杂度为O(n2)

考虑分治。对于区间[l,r],我们可以轻易求得[l,mid]和[mid+1,r]的值,关键在于求$\sum_{x\in[l,\,mid],\,y\in[mid+1,\,r]}f(x,\,y)*g(x,\,y)$

我们可以先枚举右端点r,求得每个点i到mid+1的最大值和最小值max[i]和min[i],然后从mid开始右往左枚举每一个左端点j,求得min_l,max_l,然后可以求得右端点中从左到右的第一个大于max_l,第一个小于min_l,的位置i,如图所示(我们假设min的位置在max位置的左边)

这样右边就被分成三段。

对于第一段(mid-min之间),由于最大值和最小值都是max_l,min_l,所以右端点这一段的值就是min_l*max_l*(min-mid)

对于第二段(min-max之间),由于最大值是max_l,最小值不定,不过我们可以把max_l提取出来,剩下的就是这段区间min_l的和了,所以我们可以用前缀和维护一下。smin[max-1]-smin[min-1]

对于第三段(max-r之间),由于最大值最小值都是不定,但是它们都在mid的右边,我们在分治的时候就已经算好了,直接加上去就好了  。 spul[r]-spul[max-1]

minmax右边同理。

 1 #include<iostream>
 2 #include<cstdio>
 3 #define qaq 1000000007
 4 using namespace std;
 5 const int N=500005;
 6 long long a[N],minn[N],maxx[N],sminn[N],smaxx[N],spul[N],ans;
 7 int n;
 8 void fz(long long l,long long r){
 9     if (r<l) return;
10     if (l==r){
11         ans=(ans+a[l]*a[r])%qaq;
12         return;
13     }
14     long long mid=(l+r)>>1;
15     fz(l,mid);
16     fz(mid+1,r);
17     minn[mid]=1e12;
18     maxx[mid]=0;
19     sminn[mid]=0;
20     smaxx[mid]=0;
21     spul[mid]=0;
22     for (int i=mid+1;i<=r;i++){
23         if (a[i]>maxx[i-1]) maxx[i]=a[i];
24         else maxx[i]=maxx[i-1];
25         if (a[i]<minn[i-1]) minn[i]=a[i];
26         else minn[i]=minn[i-1];
27         sminn[i]=sminn[i-1]+minn[i];
28         smaxx[i]=smaxx[i-1]+maxx[i];
29         spul[i]=(spul[i-1]+maxx[i]*minn[i])%qaq;
30     }
31     long long mi=mid;
32     long long ma=mid;
33     long long mis=1e12;
34     long long mas=0;
35     for (int i=mid;i>=l;i--){
36         if (a[i]<mis) mis=a[i];
37         if (a[i]>mas) mas=a[i];
38         while ((mi<r)&&(minn[mi+1]>=mis)) mi++;
39         while ((ma<r)&&(maxx[ma+1]<=mas)) ma++;
40         if (mi<ma)
41         ans=(ans+mis%qaq*mas%qaq*(mi-mid)%qaq+(sminn[ma]-sminn[mi])%qaq*mas%qaq+(spul[r]-spul[ma])%qaq)%qaq;
42         else
43         ans=(ans+mis%qaq*mas%qaq*(ma-mid)%qaq+(smaxx[mi]-smaxx[ma])%qaq*mis%qaq+(spul[r]-spul[mi])%qaq)%qaq;
44     }
45 }
46 int main(){
47     freopen("seq.in","r",stdin);
48     freopen("seq.out","w",stdout);
49     scanf("%d",&n);
50     for (int i=1;i<=n;i++)
51      scanf("%lld",&a[i]);
52     ans=0;
53     fz(1,n);
54     printf("%lld\n",ans);
55     return 0;
56 }

神奇的代码

乘的顺序很重要,乘的顺序很重要,乘的顺序很重要!!!(苦悲的ans那里乘的放到后面没有事先%%%就变负数waaaaaaaa了QAQ)

时间: 2024-12-26 01:32:52

【NOIP2017模拟8.5】序列问题的相关文章

冲刺Noip2017模拟赛7 解题报告——五十岚芒果酱

1.二叉树(binary) 1.二叉树 (binary.cpp/c/pas) [问题描述] 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值: (3)左.右子树也分别为二叉排序树: (4)没有键值相等的结点. 完全二叉树:只有最下面的两层结点度能够小于2,并且最下面一层的结点 都集中在该层最左边的若干位置的二叉树. 图1中,(a)和(b)是完全二叉树,(c)和(

JZOJ.5281【NOIP2017模拟8.15】钦点

Description Input Output Sample Input 4 4 2 a a b b a a b b c c d d c c d d 1 1 3 3 2 2 3 1 1 3 2 2 Sample Output d d c c  d d c c  b b a a  b b a a  Data Constraint 本题时限4s. 很明显这是一道模拟题,朴素算法O(nmq)看似过得去,实际上字符串的操作是很慢的,同样对字符串赋值10w次比对数组元素赋值10w次要慢3倍以上. 实际上

【NOIP2017模拟8.8】Trip

Description 多年之后,worldwideD厌倦竞争,隐居山林.       他的家乡开始发展起了旅游业,在一条很长的主干道上,有N个旅游景点,按顺序编号为1到N.根据游客们网上的评分,第i个景点有一个评估值a[i],为了区分开不同的景点,评估值是两两不同的.       今天有M组游客前来旅游,第i组游客选择遍历景点Li到景点Ri这一段路.他们搜到Li到Ri的所有评估值,如果对于景点j(Li≤j≤Ri),不存在景点x(Li≤x<j)满足a[x]>a[j]或不存在景点y(j<y

【NOIP2017模拟8.7】外星人的路径

Description 有一个外星人控制了你的大脑.一开始你处于原点(0,0).外星人有一个由(R,U,D,L)组成的长度为M 的操作序列,分别代表(右,上,下,左).平面上有N 个关键点,每当外星人给出一个操作,你需要在这个方向上找到最近的一个关键点,并走到那个点上.保证输入数据合法.上图为第三个样例的图示. Input 第一行两个整数N,M.接下来N 行,每行两个整数xi,yi,代表第i 个点的坐标.接下来一行,一个长度为M 的字符串,代表操作序列. Output 一行两个整数,代表最终你所

冲刺Noip2017模拟赛6 解题报告——五十岚芒果酱

1.ksum(ksum) [问题描述] Peter喜欢玩数组.NOIP这天,他从Jason手里得到了大小为n的一个正整数 数组. Peter求出了这个数组的所有子段和,并将这n(n+1)/2个数降序排序,他想 知道前k个数是什么. [输入格式] 输入文件名为 ksum.in. 输入数据的第一行包含两个整数 n 和 k. 接下来一行包含 n 个正整数,代表数组. [输出格式] 输出文件名为 ksum.out. 输出 k 个数,代表降序之后的前 k 个数,用空格隔开. [输入输出样例] ksum.i

暑假第二次考试 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱

题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n-2 个路口,分别标上号,A 农场为 1 号,B 农场为 n 号,路口分别为 2...n-1 号,从 A 农场到 B 农场有很多条路径可以到达,而 CG 发现有的路口是必须经过的,即每条路径都经过的路口,CG 要把它们记录下来,这样 CG 就可以先到那个路口,观察新牛们有没有偷懒,而你的任务就是找出所有必经路口. [输入格式] 第一行两个用空格隔开的

冲刺Noip2017模拟赛8 解题报告——五十岚芒果酱

1.鼎纹 [问题描述] 据说鼎纹的 种制造 式是 铜模印出来的,这是我国古代劳动 智慧 的结晶.铜模印过的地 ,会留下深深的印记,经过时间的炼化,洗 练成历史的遗存. 聪明的古代劳动人民拥有一个 a 行 b 列的铜模,每个位置要么是 0(代表 这个点是平的),要么是 1(代表这个点是凸起的).他们想造 个 n 行 m 列 的鼎 ,其中每个位置也都是 0 或 1,表示经过若干 次印后,每个位置的结果. 有一些要求.铜模是不能旋转和翻转的:在印的过程当中,铜模的凸起不 能出现在鼎面的外面(平的部分是

【NOIP2017模拟8.7】好的排列

Description 对于一个1->n的排列 ,定义A中的一个位置i是好的,当且仅当Ai-1>Ai 或者Ai+1>Ai.对于一个排列A,假如有不少于k个位置是好的,那么称A是一个好的排列.现在有q个询问,每个询问给定n,k,问有多少排列是好的.答案对10^9+7取模. Input 输入文件名为permutation.in.首先输入q.接下来输入q个询问n,k . Output 输出文件名为permutation.out.输出q行,每行一个整数代表答案. Sample Input 8 4

LYDSY模拟赛day3 序列

NOIP不考可持久,弃坑