Codeforces Round #435 (Div. 2) E. Mahmoud and Ehab and the function(预处理+二分)

题目链接:点我点我

题意:公式:,给出n个数,从a[1]到a[n],和m个数(b数组),然后从b数组里挑出连续的n个数(也就m-n+1中选择),按公式计算,使得f最小,

还有q次对a数组的操作(某个区间增加值,减少值),求出最小值。

题解:显然对a数组的处理非常简单,一开始确定一定值,然后update的时候,判断一下奇偶性质就可以直接加了(前一项正后一项一定是负的,可以抵消)。

然后就是b数组的处理了,一开始没处理好,一直在这边卡超时。先把b数组一项一项正负不同的加进去,然后再进行处理,得到c数组(代表b数组各种情况下的值),

然后排序二分一下。

这道题目感觉自己收获非常大,颠覆了我很多错误的想法:

1.二分函数lower_bound(c+1,c+c.size(),goal)-c中间那里加上的是数组长度而不是和sort一样是“地址”

2.upper_bound()函数是第一个大于val的位置(一直以为是小于等于val的最后一个位置,(尴尬 。。。)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 typedef long long LL;
 5 LL INF=1e18;
 6 const int N=1e5+111;
 7 LL a[N],b[N],c[N];
 8
 9 int main(){
10     LL n,m,q,pos,sum=0,tmp;
11     cin>>n>>m>>q;
12     for(int i=1;i<=n;i++){
13         scanf("%lld",&a[i]);
14         i%2==1 ? sum+=a[i] : sum-=a[i];
15     }
16     for(int i=1;i<=m;i++){
17         scanf("%lld",&tmp);
18         if(i%2==0) tmp*=-1;
19         b[i]=b[i-1]+tmp;
20     }
21     for(int i=1;i<=m-n+1;i++){
22         if(i%2) c[i]=(b[i-1]-b[i+n-1]);
23         else c[i]=(b[i+n-1]-b[i-1]);
24     }
25     sort(c+1,c+1+m-n+1);
26     LL ans=INF,x,y,z;
27     pos=lower_bound(c+1,c+m-n+1,-sum)-c;
28     if(pos==1)
29         ans=abs(sum+c[pos]);
30     else
31         ans=min(abs(sum+c[pos]),abs(sum+c[pos-1]));
32     printf("%lld\n",ans);
33     for(int k=1;k<=q;k++){
34         ans=INF;
35         scanf("%lld %lld %lld",&x,&y,&z);
36         if(y==x) {y%2==1 ? sum+=z : sum-=z;}
37         else if((y-x+1)%2) {x%2==1 ? sum+=z : sum-=z;}
38         pos=lower_bound(c+1,c+m-n+1,-sum)-c;
39         if(pos==1)
40             ans=abs(sum+c[pos]);
41         else
42             ans=min(abs(sum+c[pos]),abs(sum+c[pos-1]));
43         printf("%lld\n",ans);
44     }
45     return 0;
46 }
时间: 2024-10-13 08:30:57

Codeforces Round #435 (Div. 2) E. Mahmoud and Ehab and the function(预处理+二分)的相关文章

Codeforces Round #435 (Div. 2) D. Mahmoud and Ehab and the binary string[二分]

题目:http://codeforces.com/problemset/problem/862/D 题意:交互题,询问15次以内Hamming distance,输出一个二进制串里任意一个0或1的位置 题解:极简单的二分,从最后一位先判断一个,然后二分 根据上次和本次的距离差是否等于二分长度判断在左端还是右端有需要寻找的值寻找另一个. 1 #define _CRT_SECURE_NO_DEPRECATE 2 #pragma comment(linker, "/STACK:102400000,10

D. Mahmoud and Ehab and the binary string Codeforces Round #435 (Div. 2)

http://codeforces.com/contest/862/problem/D 询问题 fflush(stdout) 调试: 先行给出结果,函数代替输入 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <se

E. Mahmoud and Ehab and the function Codeforces Round #435 (Div. 2)

http://codeforces.com/contest/862/problem/E 二分答案 一个数与数组中的哪个数最接近: 先对数组中的数排序,然后lower_bound 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #includ

Codeforces Round #396 (Div. 2)C. Mahmoud and a Message(dp)

题目链接:http://codeforces.com/problemset/problem/766/C 题意:给你一组小写字母组成的字符串,和26个数字,分别对应26位小写字母能够存在的字符串的最大长度. 要求:①:求出最多的划分方案 ②:求出分配方案中,最长的子串长度 ③:求出分配方案中,最少分成的子串数 思路:关于①:设置dp[i],dp[i]表示在第i个字符后面有一个横杠的方案数,从第i个往前枚举前一个横杠的位置j. 举个例子,有子串abc,当横杠断在a处,有一种方案,dp[1]=1:当横

Codeforces Round #435 (Div. 2) c+d

C:给n和k要求,找出n个不同的数,使得亦或起来等于k 可以先预处理从1到1e5,找亦或起来等于(11111111111111111)(二进制)的所有对数,然后四个一起亦或就是0了,再和k亦或 可以看出要分四种情况讨论,对于n%4=p的情况,应该找到p-1个不同的数亦或起来等于0,可以小范围的p-1重循环搜索,对于n%4==2&&x==0的情况要注意特判,可以用6重循环,每层不超过10 代码过于复杂了,应该可以简化一下 #include<bits/stdc++.h> #defi

Codeforces Round #396(Div. 2) A. Mahmoud and Longest Uncommon Subsequence

[题意概述] 找两个字符串的最长不公共子串. [题目分析] 两个字符串的最长不公共子串就应该是其中一个字符串本身,那么判断两个字符串是否相等,如果相等,那么肯定没有公共子串,输出"-1".否则就是两个字符串中长的最长的长度. [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() { 4 char str1[100005],str2[100005]; 5 scanf("%s%s"

Codeforces Round #371 (Div. 1) D - Animals and Puzzle 二维ST表 + 二分

D - Animals and Puzzle #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define ull unsigned long long using namespace std; const in

Codeforces Round #619 (Div. 2) Ayoub&#39;s function

Ayoub thinks that he is a very smart person, so he created a function f(s)f(s) , where ss is a binary string (a string which contains only symbols "0" and "1"). The function f(s)f(s) is equal to the number of substrings in the string s

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i