A题意(取余最长路):

  佳佳有一个n*m的带权矩阵,她想从(1,1)出发走到(n,m)且只能往右往下移动,她能得到的娱乐值为所经过的位置的权的总和。

有一天,她被下了恶毒的诅咒,这个诅咒的作用是将她的娱乐值变为对p取模后的值,这让佳佳十分的不开心,因为她无法找到一条能使她得到最大娱乐值的路径了!

她发现这个问题实在是太困难了,既然这样,那就只在3*n的矩阵内进行游戏吧!

现在的问题是,在一个3*n的带权矩阵中,从(1,1)走到(3,n),只能往右往下移动,问在模p意义下的移动过程中的权总和最大是多少。

n(1<=n<=100000),p(1<=p<=1000000000)。

  最简单的思路就是 搞一搞前缀和 枚举两个转折点 那么复杂度是n^2。BOOM!

  设三段的前缀和和 分别为s1,s2,s3  设转折点分别为(2,x1) (2,x2)

再仔细想一想p-1肯定是我们能得到的最大值,那么我们可以优化到枚举一个转折点(第二个转折点),前两段的结果丢在set里;

二分就OK了。

但是为了不影响二分的结果,做了一点改动(set不能丢入1,1->2,x1->2,x2)。应丢入1,1->2,x1->2,n 的和

前缀和表示为 s2[n]+s1[x1]-s2[x1-1];

二分的值变为((p-1)-(s3[n]-s3[x2-1])+((s2[n]-s2[x2]))+p)%p,每次更新答案就OK了

再观察一下发现插入和查询的时候都加了s2[n]

所以我们把s2[n]去掉=。=

然后s3[]用的一直是x2->n的和  这里应该用个后缀和的

写的时候手残读入错误,导致以为思路不对 --- 浪费了很多时间  (被自己气笑

PS:啊现在的我们是多么幸福,现成的STL啦啦啦;

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <set>
using namespace std;
const int maxn = 1e5+;
typedef long long ll;
inline void r(ll&num){
num=;ll f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')num=num*+ch-'',ch=getchar();
num*=f;
}
inline void r(int &num){
num=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')num=num*+ch-'',ch=getchar();
num*=f;
}
ll s1[maxn],s2[maxn],s3[maxn];
int main()
{
int n;
ll p;
r(n),r(p);
for(int i=;i<=n;i++)
{
r(s1[i]);
s1[i]=(s1[i]+s1[i-])%p;
}
for(int i=;i<=n;i++)
{
r(s2[i]);
s2[i]=(s2[i]+s2[i-])%p;
}
for(int i=;i<=n;i++)
{
r(s3[i]);
s3[i]=(s3[i]+s3[i-])%p;
}
set<ll>s;
ll ans = -;
set<ll>::iterator it;
ll sum;
ll cnt;
for(int i=;i<=n;i++)
{
s.insert(((s1[i]-s2[i-])%p+p)%p);
sum = (s3[n]-s3[i-]+s2[i])%p;
cnt = ((p-sum)%p+p)%p;
it = s.lower_bound(cnt);
if(it!=s.begin()) it--;
ans = max(ans,((((*it)+sum)+p)%p));
}
cout<<ans<<endl;
return ;
}

有漏洞

这里有一个小技巧  我们如果想找出小于等于X的最大值 我们只需lower_boundX+1  得到大于等于X+1的区间[it,end)  那么 [begin,it) 就是小于等于X的区间;

if it == begin 不存我们要的值

else *(--it)就是我们要的值辣

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <set>
using namespace std;
const int maxn = 1e5+;
typedef long long ll;
inline void r(ll&num){
num=;ll f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')num=num*+ch-'',ch=getchar();
num*=f;
}
inline void r(int &num){
num=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')num=num*+ch-'',ch=getchar();
num*=f;
}
ll s1[maxn],s2[maxn],s3[maxn];
int main()
{
int n;
ll p;
r(n),r(p);
for(int i=;i<=n;i++)
{
r(s1[i]);
s1[i]=(s1[i]+s1[i-])%p;
}
for(int i=;i<=n;i++)
{
r(s2[i]);
s2[i]=(s2[i]+s2[i-])%p;
}
for(int i=;i<=n;i++)
{
r(s3[i]);
s3[i]=(s3[i]+s3[i-])%p;
}
set<ll>s;
ll ans = -;
set<ll>::iterator it;
ll sum;
ll cnt;
for(int i=;i<=n;i++)
{
s.insert(((s1[i]-s2[i-])%p+p)%p);
sum = (s3[n]-s3[i-]+s2[i])%p;
cnt = ((p-sum)%p+p)%p;
it = s.lower_bound(cnt);
if(it!=s.begin()) it--;
else it = --s.end();
ans = max(ans,((((*it)+sum)+p)%p));
}
cout<<ans<<endl;
return ;
}

AC代码

C题意(比大小):

   有两个数列A和B 已知A_0,a,b,N A_n=A_(n-1)*a+b (n>=1) B数列满足 B_n=2*B_(n/2) + 1 (n为偶数) B_n=2*B_((n-1)/2) + (n+1)/2 (n为奇数)
现在问B数列的第A_N项和第(A_N)+1项的关系
T组数据 A_0,a,b,N<=1e15

T<=100
 
N 1e15  没规律铁定做不了
B_0 = -1;
然后把B序列暴力出来前40项  发现规律 除了0-3 不符合规律外 后面连续的四个都符合规律
这时候就需要考虑A序列了 如果发现A_N小于4 那就需要特判 (题意说的也不是太清如果 A_0<=3 ,  a = 0,b = 0, N = 1e15 这个数据肯定T
然后暴力N项 发现还有规律
N<=3 特判
N>=4  走N次 和 N%4+4结论一样
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <set>
using namespace std;
typedef long long ll;
inline void r(ll&num){
num=;ll f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')num=num*+ch-'',ch=getchar();
num*=f;
}
inline void r(int &num){
num=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')num=num*+ch-'',ch=getchar();
num*=f;
}
ll a,b,N;
ll A0,AN,A;
bool flag = false;
ll B[];
void check()
{
if(flag)
{
A+=;
}
if(B[A]==B[A+])
{
puts("=");
}
else{
if(B[A]<B[A+])
{
puts("<");
}
else{
puts(">");
}
}
}
int main()
{
int T;
r(T);
B[] = -;
//cout<<"-1"<<endl;
for(int i=;i<;i++)
{
B[i] = B[i/]*+;
if(i&)
{
B[i]+=i/;
}
//cout<<B[i]<<endl;
}
while(T--)
{
flag = false;
r(A0),r(a),r(b),r(N);
A = A0;
for(ll i=;i<=N;i++)
{ if(A>)
{
flag = true;
break;
}
A = A*a+b;
//A%=4;
}
A = A0%;
N = N > ? N % + : N;
for(int i=;i<=N;i++)
{
A = A*a+b;
A%=;
}
check();
}
return ;
}

AC代码

 

算法马拉松13 A-E解题报告的更多相关文章

  1. 51nod算法马拉松13

    A 取余最长路 不难发现路径可以拆成三条线段,只要知道两个转折点的位置就能计算出答案. 设sum(i,l,r)表示第i行从l到r元素的和,则答案可以表示为sum(1,1,x)+sum(2,x,y)+s ...

  2. Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)

     http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...

  3. LeetCode :1.两数之和 解题报告及算法优化思路

    最近开始重拾算法,在 LeetCode上刷题.顺便也记录下解题报告以及优化思路. 题目链接:1.两数之和 题意 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 ...

  4. 2021字节跳动校招秋招算法面试真题解题报告--leetcode206 反转链表,内含7种语言答案

    206.反转链表 1.题目描述 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1-> ...

  5. 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案

    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...

  6. ACM -- 算法小结(七)Phone list解题报告

          HDOJ -- Phone list解题报告 问题描述:给出一些电话号码,如果有共同前缀则输出NO,如果没有则输出YES. 解题关键:将电话号码进行字符串排序,相邻的电话号码进行比较 Sa ...

  7. 杭州电子科技大学Online Judge 之 “确定比赛名次(ID1285)”解题报告

    杭州电子科技大学Online Judge 之 "确定比赛名次(ID1285)"解题报告 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozh ...

  8. USACO Section1.4 Arithmetic Progressions 解题报告

    ariprog解题报告 —— icedream61 博客园(转载请注明出处)-------------------------------------------------------------- ...

  9. 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

    2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...

随机推荐

  1. Flutter实战视频-移动电商-10.首页_FlutterSwiper轮播效果制作

    10.首页_FlutterSwiper轮播效果制作 博客地址: https://jspang.com/post/FlutterShop.html#toc-5c2 flutter_swiper http ...

  2. shell编程流程控制

    前言: 在linux shell中,通常我们将一些命令写在一个文件中就算是一个shell脚本了,但是如果需要执行更为复杂的逻辑判断,我们就需要使用流程控制语句来支持了. 所谓流程控制既是通过使用流程控 ...

  3. 解决“System.Data.OracleClient需要Oracle客户端软件8.1.7或更高版本”

    问题描述:远程访问该数据库(客户端同样是Oracle11g)提示“System.Data.OracleClient需要Oracle客户端软件8.1.7或更高版本”. 解决的办法: 1.一定要关闭Win ...

  4. Lua 不是 C++

    http://blog.codingnow.com/2008/08/lua_is_not_c_plus_plus.html 嗯,首先,此贴不是牢骚帖. 话题从最近私人的一点工作开始.应 dingdan ...

  5. 洛谷 - P5429 - Fence Planning - 并查集

    https://www.luogu.org/problemnew/show/P5429 很明显是要维护整个连通块的共同性质,并查集一搞就完事了. #include<bits/stdc++.h&g ...

  6. 算法学习--Day7

    今天多做一些杂题练习一下. 第一题: 题目描述 在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密,简单的加密算法虽然不足以完全避免情报被破译,但仍然能防止情报被轻易的识别.我们给出 ...

  7. 51nod1267(双指针)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1267 题意:中文题诶- 思路:双指针 求a+b+c+d=0,令 ...

  8. 2014-6-28 NOIP模拟赛

    [今天我出的三道题目全部是图论哦,请大家轻虐] 1.魔术球问题弱化版(ball.c/.cpp/.pas) 题目描述 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的 ...

  9. web前端篇:JavaScript正则表达式

    目录 JavaScript正则表达式 1.创建正则表达式 1.1方法1:直接量语法 1.2 方法2:创建RegExp对象的语法 1.3 区别: 1.4正则表达式使用 2.正则对象的属性 2.1.属性 ...

  10. JSP | 基础 | 连接数据库

    package util; import java.sql.DriverManager; import java.sql.SQLException; import com.mysql.jdbc.*; ...