【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】
目录:
1:一道简单题【树形问题】(Bzoj 1827 奶牛大集会)
2:一道更简单题【矩阵乘法】【快速幂】
3:最简单题【技巧】
话说这些题目的名字也是够了。。。。
题目:
1、一道简单题
时间1s
题目描述
Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会。当然,她会选择最方便的地点来举办这次集会。每个奶牛居住在 N(1<=N<=100,000) 个农场中的一个,这些农场由N-1条道路连接,并且从任意一个农场都能够到达另外一个农场。道路i连接农场A_i和B_i(1 <= A_i <=N; 1 <= B_i <= N),长度为L_i(1 <= L_i <= 1,000)。集会可以在N个农场中的任意一个举行。另外,每个牛棚中居住着C_i(0 <= C_i <= 1,000)只奶牛。在选择集会的地点的时候,Bessie希望最大化方便的程度(也就是最小化不方便程度)。比如选择第X个农场作为集会地点,它的不方便程度是其它牛棚中每只奶牛去参加集会所走的路程之和,(比如,农场i到达农场X的距离是20,那么总路程就是C_i*20)。帮助Bessie找出最方便的地点来举行大集会。
输入
第一行:一个整数N
第二到N+1行:第i+1行有一个整数C_i
第N+2行到2*N行,第i+N+1行为3个整数:A_i,B_i和L_i。
输出
一个数字表示答案
样例
Input |
Output |
5 |
15 |
对于
20%数据n<20
50%数据 n<2000
100%数据n<100,000
2、一道更简单题
时间1s
描述
有n个数围成一圈,每次操作后每个数变成和他距离在d以内的数字之和,求k次操作后每个数字模1000000007分别是多少有n个数围成一圈,每次操作后每个数变成和他距离在d以内的数字之和,求k次操作后每个数字模1000000007分别是多少
输入
第一行三个数n, d, k (1 ≤ n ≤ 1000, 0 ≤ d < n / 2 , 1 ≤ k ≤ 100 000 000),
第二行有n个正数,每个的大小都在int范围内
输出
一行n个数,空格隔开,表示结果。
样例
Input |
Ouput |
5 1 1 1 2 10 3 6 |
9 13 15 19 10 |
10%数据满足n*k<10^6
30%数据满足 n<=100
50%数据满足 n<=500
100%数据满足n<=1000
3、最简单的题
时间1s
题目描述
给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数。
例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7
输入
第一行2个数n,k。
输出
一个数 j(n,k)。
样例
Input |
Output |
5 3 |
7 |
50% 数据 满足 n<1e6
100%数据 满足 n<1e12 k<=n
解题报告:
第一题:参考Regina8023(CSDN)的思路解释:
发现这些农场构成了一棵树。
所以首先以任意一个点为根建树,并把这个点当做目标点。
那么最终的答案就是每条树边乘有几头牛要走,一条边有几头牛要走其实就是这条边下面有几个子孙。
于是我们预处理出以1为根的树的答案,并求出每个节点有几个子孙,然后O(1)转移到他的儿子的答案,这个儿子又可以O(1)转移到他自己的儿子。。。
因此我们用O(n)时间就求出以每个点为目的地的路程和,输出最小即可。
转移方法是:
根变成儿子的时候,只有连接儿子的边要变化,根据预处理出的每个节点的儿子,即可转移。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define LL long long
using namespace std;
const int maxn=;
LL n,ans=1e15,sum,c[maxn];
LL he[maxn],ne[maxn*],to[maxn*],w[maxn*],tot;
LL f[maxn],cost[maxn],num[maxn],len[maxn];
void add(LL a,LL b ,LL x)
{
tot++;
ne[tot]=he[a];
w[tot]=x;
to[tot]=b;
he[a]=tot;
}
void ready(LL x ,LL fa)//当前节点x,它的father fa
{
for (LL i=he[x];i;i=ne[i])
if (to[i]!=fa)//!!! 防止原路返回
{
len[to[i]]=len[x]+w[i];
ready(to[i],x);//从上到下
cost[x]+=cost[to[i]];//从x到根节点(包括它的所有儿子)的总路程
num[x]+=num[to[i]];//从x向下的所有奶牛数
}
cost[x]+=len[x]*c[x];//加上自己
num[x]+=c[x];
}
void dfs(LL x,LL fa)
{
for (LL i=he[x];i;i=ne[i])
if (to[i]!=fa)
{
f[to[i]]=f[x]+(sum-num[to[i]])*w[i]-num[to[i]]*w[i];
//将集合地点向下移,用O(1)算它的总路程
dfs(to[i],x);
}
}
int main()
{
freopen("A.in","r",stdin);
freopen("A.out","w",stdout);
cin>>n;
for (LL i=;i<=n;i++)
{
scanf("%I64d",&c[i]);
sum+=c[i];
}
for (LL i=;i<n;i++)// < n not <=n
{
LL a,b,x;
scanf("%I64d%I64d%I64d",&a,&b,&x);
add(a,b,x);
add(b,a,x);
}
ready(,);//预处理任意根节点的一棵树
f[]=cost[];
dfs(,);
for (LL i=;i<=n;i++)
{
if (f[i]<ans)
ans=f[i];
}
cout<<ans;
return ;
}
第二题:如果纯模拟的话,按理说可以得10分,但是我的纯模拟怎么一分都没有。这道题要用矩阵乘法+快速幂。具体的推导方法是这样的:
首先,我们从一个点的多次修改得到系数:
如 a0,a1,a2,a3,a4
第一次:a0=a0+a1+a4 第二次:a0=3*a0+2*a1+2*a4+a2+a3第三次:a0=7*a0+6*a1+6*a4+4*a2+4*a3
a1=a0+a1+a2 a1=3*a1+2*a0+2*a2+a3+a4 ......
a2=a1+a2+a3 a2=3*a2+2*a3+2*a1+a4+a0 ......
...... ......
按照a0~a4提取出它们的系数:1*a0 1*a1 0*a2 0*a3 1*a4
3*a0 2*a1 1*a2 1*a3 2*a4
7*a0 6*a1 4*a2 4*a3 6*a4
所以我们想到了矩阵相乘用 1 1 0 0 1 a0 a0+a1+a4
1 1 1 0 0 a1 a0+a1+a2
0 1 1 1 0 * a2 = a1+a2+a3
0 0 1 1 1 a3 a2+a3+a4
1 0 0 1 1 a4 a3+a4+a1
如果k>1的话,就要再用新的数列重复以上操作,所以,运用矩阵乘法的结合律,我们可以用快速幂求解。
又发现左边矩阵很有规律,所以可以简化为一维数组,具体的解释和注意在代码中了。
#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;
const LL INF=;
const LL maxn=;
LL n,d,k;
LL num[maxn],tmp[maxn];
void cheng(LL a[],LL b[])//a num ,b tmp
{
LL c[maxn];
memset(c,,sizeof(c));//局部变量 c 初值随机,需要重定为 0
for (LL i=;i<n;i++)//c[0]=a0*b0+a1*b1+a2*b2+a3*b3+a4*b4
for (LL j=;j<n;j++)//c[1]=a0*b4+a1*b0+a2*b1+a*b2+a4*b3
{
if (i>j) c[i]=(c[i]+a[j]*b[n+j-i])%INF;//发现当i>j时,b取b[n+j-i]
else
c[i]=(c[i]+a[j]*b[j-i])%INF;//当i<=j时,b取 b[j-i]
}
for (LL i=;i<n;i++)
a[i]=c[i]%INF;
}
int main()
{
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
cin>>n>>d>>k;
for (LL i=;i<n;i++)
scanf("%d",&num[i]);
tmp[]=;
for (LL i=;i<=d;i++)
tmp[i]=tmp[n-i]=;
while (k>)
{
if (k&) cheng(num,tmp);
k=k>>;
cheng(tmp,tmp);
}
for (LL i=;i<n;i++)
printf("%I64d ",num[i]);
return ;
}
第三题:主要是打表找规律,比如从n=100,k=100打表出100/(1~100)=x.....y 从中找到规律:
100/(51~100)=1....(0、1~48、49)
100/(34~50)=2......(0、2~30、32)
100/(26~33)=3......(1,4~19,22)
100/(21~25)=4......(0,4,~12,16)
100/(17~20)=5......(0,5,10,15)
100/(15,16)=6......(4,10)
.......
从100/12 开始余只有一个。所以从1~12就循环求解。另外,当n>k时,直接余数=k 加上去就可以了。
#include<iostream>
#include<cstdio>
#define LL long long
using namespace std;
LL n,k;
LL ans;
int main()
{
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
cin>>n>>k;
if (n>k)
{
ans+=(n-k)*k;
n=k;
}
LL l,x,d,next,r;
for (LL i=n;i>=;i=next)
{
d=k/i;//等差值
l=k%i;//a(1)
next=k/(d+);//下一个区间的右边界
x=i-next;//区间个数 n
r=k%(next+);//a(n)
if (l==r) break;
else
//S(n)=n*a(1)+( n*(n-1)/2 )*d
ans+=x*l+(x*(x-)/)*d;
}
for (LL i=;i<=next+;i++)
ans+=k%i;
cout<<ans;
return ;
}
【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】的更多相关文章
- Qbxt 模拟赛 Day4 T2 gcd(矩阵乘法快速幂)
/* 矩阵乘法+快速幂. 一开始迷之题意.. 这个gcd有个规律. a b b c=a*x+b(x为常数). 然后要使b+c最小的话. 那x就等于1咯. 那么问题转化为求 a b b a+b 就是斐波 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- POJ 1001 解题报告 高精度大整数乘法模版
题目是POJ1001 Exponentiation 虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...
- [JZOJ4272] [NOIP2015模拟10.28B组] 序章-弗兰德的秘密 解题报告(树形DP)
Description 背景介绍弗兰德,我不知道这个地方对我意味着什么.这里是一切开始的地方.3年前,还是个什么都没见过的少年,来到弗兰德的树下,走进了封闭的密室,扭动的封尘已久机关,在石板上知道了这 ...
- nowcoder(牛客网)提高组模拟赛第四场 解题报告
T1 动态点分治 就是模拟..... 但是没有过!! 看了题解之后发现.... 坑点:有可能 \(x<=r\),但是
- nowcoder 提高组模拟赛 最长路 解题报告
最长路 链接: https://www.nowcoder.com/acm/contest/178/A 来源:牛客网 题目描述 有一张 \(n\) 个点 \(m\) 条边的有向图,每条边上都带有一个字符 ...
- [jzoj 6093] [GDOI2019模拟2019.3.30] 星辰大海 解题报告 (半平面交)
题目链接: https://jzoj.net/senior/#contest/show/2686/2 题目: 题解: 说实话这题调试差不多花了我十小时,不过总算借着这道题大概了解了计算几何的基础知识 ...
- [CQOI2009] 叶子的颜色 解题报告(树形DP)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1304 Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为 ...
- 「2018-12-02模拟赛」T2 种树 解题报告
2.种树(tree.pas/cpp/in/out) 问题描述: Fanvree 很聪明,解决难题时他总会把问题简单化. 例如,他就整天喜欢把图转化为树.但是他不会缩环,那他怎么转化呢? 这是一个有 n ...
随机推荐
- Python学习笔记6-字典
定义 使用键值对, >>> person = {"name":"keven","age":15,"gender& ...
- 关于level DB的相关资料
可以参考: http://blog.csdn.net/houzengjiang/article/details/7718548 http://www.cnblogs.com/haippy/archiv ...
- JavaSE复习_9 集合框架复习
△列表迭代器也是不支持在迭代的时候添加元素的,只是列表迭代器自己定义了增删的方法而已.迭代器可以看成实在两个元素之间的指针,每当调用next就跳过一个元素并返回刚刚跳过的元素. △HashTable不 ...
- linux简单配置
lsof -i lsof -i:211.判断apache查找httpd路径: ps aux | grep httpd 结果: /usr/local/apache/bin/httpd /usr/loc ...
- java.lang.UnsupportedClassVersionError: org/sonatype/nexus/bootstrap/jsw/JswLauncher : Unsupported major.minor version 51.0
jdk 版本不对,需要修改jdk的版本
- OpenGL的glPushMatrix和glPopMatrix矩阵栈顶操作函数详解
OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的.opengl中的变换一般包括视图变换.模型变换.投影变换等,在每次变换后,opengl将会呈 ...
- Htmlt_Div+Css简介
DIV+CSS是网站标准(或称“WEB标准”)中常用术语之一,通常为了说明与HTML网页设计语言中的表格(table)定位方式的区别,因为XHTML网站设计标准中,不再使用表格定位技术,而是采用DIV ...
- Android menu 简单创建
在android 中与menu相关的类有4个: Menu:菜单的父窗口,用于创建一个菜单,是subMenu,ContentMenu,MenuItem等的父接口:SubMenuyo用于创建子菜单,Con ...
- iOS 使用Keychain 保存 用户名和密码到 本地
iOS 使用Keychain 保存 用户名和密码到 本地 之前曾把一些简单的数据保存在了plist,文件,及NsuserDefault里面, 但是如果要保存密码之类的,保存在本地就很不安全了: 但是利 ...
- Ubuntu 系统下 mongodb 安装和配置
安装 MongoDB sudo apt-get install mongodb sudo apt-get install mongodb 关闭/启动 sudo service mongodb stop ...