TCPThree_C杯 Day2
T1
我已经被拉格朗日插值蒙蔽了双眼,变得智障无比。
第一反应就是拉格朗日插值,然后就先放下了它。
模数那么小,指数那么大,这是一套noip模拟题,拉格朗日,你脑袋秀逗了?
无脑暴力20分贼开心。
正解:
因为模数很小,所有大于模数的数可以先mod再算,就相当于多次用了从0到mod-1的答案。
对于0到mod-1(相当于1到mod)可以只算素数,由于这个函数是积性函数,所以可以在 线性筛素数 的时候顺便求i的k次方
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=3e6+10;
long long n,m,mod,ans;
long long f[maxn]; long long rs;
long long qp(long long x,long long k) {
if(x<=1) return x;
rs=1;
while(k&&rs) {
if(k&1) rs=rs*x%mod;
x=x*x%mod;k>>=1;
}
return rs;
} bool ok[maxn];
int prime[maxn/5],tot_p;
void get_p() {
f[1]=1;
for(int i=2;i<=mod;++i) {
if(!ok[i]) prime[++tot_p]=i,f[i]=qp(i,m);
for(int j=1;j<=tot_p&&prime[j]<=mod/i;++j) {
ok[i*prime[j]]=1;f[i*prime[j]]=f[i]*f[prime[j]]%mod;
if(i%prime[j]==0) break;
}
}
} int main() {
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
cin>>mod>>m>>n;
get_p();
for(int i=1;i<=mod;++i) f[i]=(f[i-1]+f[i])%mod;
ans=(f[mod]*(n/mod)+f[n%mod])%mod;
cout<<ans;
fclose(stdin);fclose(stdout);
return 0;
}
T2
二分,线段覆盖,很裸,具体见代码:
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1e5+10;
const double pi=acos(-1);
int n;double L,R,maxh=0;
double dn[maxn][4]; struct Node{
double x,y;
}node[maxn]; bool cmp(const Node& a,const Node& b) {
return a.y<b.y;
} bool check(double h) {
int tot=0;double x,minl=1e4,maxr=-1e4;
for(int i=1;i<=n;++i) {
if(dn[i][2]<h) continue;
x=tan(pi*dn[i][3]/180.0)*(dn[i][2]-h);
if(dn[i][1]-x>R||dn[i][1]+x<L) continue;
node[++tot].x=dn[i][1]-x;
node[tot].y=dn[i][1]+x;
minl=min(minl,node[tot].x);
maxr=max(maxr,node[tot].y);
}
if(minl>L||maxr<R) return 0;
sort(node+1,node+tot+1,cmp);
minl=1e4;
for(int i=tot;i>1;--i) {
minl=min(minl,node[i].x);
if(node[i-1].y<minl&&(node[i-1].y<R&&minl>L)) return 0;
}
return 1;
} int main() {
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
cin>>n>>L>>R;
for(int i=1;i<=n;++i)
{
scanf("%lf%lf%lf",&dn[i][1],&dn[i][2],&dn[i][3]);
maxh=max(maxh,dn[i][2]);
}
double l=0,r=maxh,mid;
while(r-l>=1e-7) {
mid=(l+r)/2.0;
if(check(mid)) l=mid;
else r=mid;
}
printf("%.7lf",l);
fclose(stdin);fclose(stdout);
return 0;
}
T3:
我写的线段树你不会杀了我吧(所以竟然比pyh跑得快?!)。
我建了n颗线段树(不要问我为什么建这么多),但是并不用把所有节点开完,每次修改的时候再新建节点。
对于第i颗线段树的第j个位置表示把前i个数合并,且合并后最大数为j,需要的最小合并次数。
我们知道,如果最后合并出来的东西是确定的,无论合并顺序是否相同,合并次数是确定的。
具体地说:如果我把第 x 到第 y 共( y - x +1)个数合并需要合并( y - x )次。
那么我们每次从前到后扫一遍,扫到一个 i ,我们从 i - 1 到 0逆序枚举 j ,我们把从第 j+1到i的所有数合并,(在第j颗线段树里面查询<=合并后的值的最小合并次数)并计算答案(插入第i颗线段树)。
关于优化:就是为什么从 i - 1 到 0逆序枚举 j ,我们知道如果存在一个 k ( k > j )所以sum[i]-sum[k]<sum[i]-sum[j],那么如果第i颗线段树中 最大数为sum[i]-sum[k]的点的需要的最小合并次数比 最大数为sum[i]-sum[j]的点的需要的最小合并次数 要小,那么再更新最大数为sum[i]-sum[j]的点就不必要了。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1500+10,INF=1e6;
int n,a[maxn],sum[maxn],maxnum=0,ans,tot; int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
} struct Node{
int l,r,minnum,son[2];
}node[maxn*4000]; void chge(int pos,int t,int x) {
node[pos].minnum=min(node[pos].minnum,x);
if(node[pos].l==node[pos].r) return;
int mid=(node[pos].l+node[pos].r)>>1;
if(t<=mid) {
if(!node[pos].son[0]) {
node[pos].son[0]=++tot;
node[tot].l=node[pos].l;
node[tot].r=mid;
node[tot].minnum=INF;
}
chge(node[pos].son[0],t,x);
}
else {
if(!node[pos].son[1]) {
node[pos].son[1]=++tot;
node[tot].l=mid+1;
node[tot].r=node[pos].r;
node[tot].minnum=INF;
}
chge(node[pos].son[1],t,x);
}
} int q(int pos,int r) {
if(!pos) return INF;
if(node[pos].r<=r) return node[pos].minnum;
int mid=(node[pos].l+node[pos].r)>>1;
if(r<=mid) return q(node[pos].son[0],r);
else return min(q(node[pos].son[0],mid),q(node[pos].son[1],r));
} int main() {
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
n=read();int x,y; ans=n-1;
for(int i=1;i<=n;++i) a[i]=read(),sum[i]=a[i]+sum[i-1];
for(int i=1;i<=n;++i) node[i].l=1,node[i].r=sum[i],node[i].minnum=INF;
tot=n;int ff;
for(int i=1;i<=n;++i) {
ff=ans;
for(int j=i-1;j>=0;--j) {
x=sum[i]-sum[j];
if(j) y=q(j,x)+i-j-1; else y=i-j-1;
if(y>=ff) continue;//优化
chge(i,x,y);ff=y;
}
}
ans=min(ans,q(n,sum[n]));
cout<<ans;
fclose(stdin);fclose(stdout);
return 0;
}
/*
7
3 4 8 2 3 4 7
*/
其实那个线段树并不必要,直接用n平方算法过,证明在代码下面。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1500+10,INF=1e6;
int n,sum[maxn],ans[maxn],g[maxn]; int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
} int main() {
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
n=read();int x,y;
for(int i=1;i<=n;++i) sum[i]=read()+sum[i-1];
for(int i=1;i<=n;++i) {
for(int j=i-1;j>=0;--j) {
g[i]=x=sum[i]-sum[j];
if(x>=g[j]) {
ans[i]=ans[j]+i-j-1;
break;
}
}
}
cout<<ans[n];
return 0;
}
zyh说这道题可以加一个单调队列变成nlogn,但是实际运行比n2慢。%%%
题解(来源:https://wenku.baidu.com/view/d6726d0552ea551810a68772.html):
形成非降序列的最少合并次数
给定一个序列,你每次可以合并相邻两个元素,新的元素为这两个元素的和。你需要使得若干次合并之后的序列非降,求最小合并次数。
[LYP的并,tyvj2008tower,QW的CCL]
解析:设f[i]表示以i结尾的所有数分成的组数,g[i]存第i个数结尾的数它这组的数的值,那么转移为:
f[i]=max{f[j]+1}(j<i,s[i]-s[j]>=g[j]),转移f[i]的同时转移g[i]为s[i]-s[j],
初始f[i]=1,g[i]=s[i].
通过观察我们发现,设当前分了k组,第i个数,最坏分到第k组,所以,f数组一定是不减的,所以j只要倒着循环,找到第一个满足s[i]-s[j]>=g[j]的j,转移f[i].
开始认为此方程有问题 {存在p,使得f[p]在所有已得到的f值中最大;若存在q满足f[q]<f[p]且q>p,则此方程有bug。但是这种情况不存在!f值单调非降!},
另外有单调队列做法。
TCPThree_C杯 Day2的更多相关文章
- TCPThree_C杯 Day1
题解 或 正规题解 已经很详细,不再赘述. 跟着wjx打代码,不怕卡题. 忘开long long智障错误第四次左偏树
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- Tyvj P2044 ["扫地"杯III day2]旅游景点
二次联通门 : Tyvj P2044 ["扫地"杯III day2]旅游景点 /* Tyvj P2044 ["扫地"杯III day2]旅游景点 并查集 先把大 ...
- NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day2题解
上星期打的...题有点水,好多人都AK了 T1排个序贪心就好了 #include<iostream> #include<cstring> #include<cstdlib ...
- NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解
肝了两题... T1一眼题,分解质因数,找出2的个数和5的个数取min输出 #include<iostream> #include<cstring> #include<c ...
- 【2018.10.18】noip模拟赛Day2 地球危机(2018年第九届蓝桥杯C/C++A组省赛 三体攻击)
题目描述 三体人将对地球发起攻击.为了抵御攻击,地球人派出了 $A × B × C$ 艘战舰,在太 空中排成一个 $A$ 层 $B$ 行 $C$ 列的立方体.其中,第 $i$ 层第 $j$ 行第 $k ...
- 【从零开始学BPM,Day2】默认表单开发
[课程主题]主题:5天,一起从零开始学习BPM[课程形式]1.为期5天的短任务学习2.每天观看一个视频,视频学习时间自由安排. [第二天课程] Step 1 软件下载:H3 BPM10.0全开放免费下 ...
- 2015游戏蛮牛——蛮牛杯第四届开发者大赛 创见VR未来开启报名
蛮牛杯启动了,大家开始报名! http://cup.manew.com/ 这不是一篇普通的通稿,别着急忽略它.它是一篇可以让你梦想变现的通稿! 从某一天开始,游戏蛮牛就立志要为开发者服务,我们深知这一 ...
- NOIp2016 Day1&Day2 解题报告
Day1 T1 toy 本题考查你会不会编程. //toy //by Cydiater //2016.11.19 #include <iostream> #include <cstd ...
随机推荐
- PAT甲级——A1014 Waiting in Line
Suppose a bank has N windows open for service. There is a yellow line in front of the windows which ...
- 【DM642】ICELL Interface—Cells as Algorithm Containers
ICELL Interface—Cells as Algorithm Containers: DSP的算法标准(XDAIS)为算法提供了一个标准的接口.这样我们就可以使用第三方的算法.For tech ...
- 《数据结构与算法分析——C语言描述》ADT实现(NO.01) : 栈(Stack)
这次的数据结构是一种特殊的线性表:栈(Stack) 栈的特点是后入先出(LIFO),可见的只有栈顶的一个元素. 栈在程序中的地位非常重要,其中最重要的应用就是函数的调用.每次函数调用时都会创建该函数的 ...
- std::map插入失败会返回什么
总所周知,map不能存在2个相同的key,那么如果是后插入的key,对应的value不会添加上去,也不会覆盖原来的,此时会返回一个std::pair<iterator,bool>,可以根据 ...
- Tensorflow技巧
1.尽量控制图片大小在1024以内,不然显存会爆炸. 2.尽量使用多GPU并行工作,训练下降速度快. 3.当需要被检测的单张图片里物体太多时,记得修改Region_proposals的个数 4.测试的 ...
- TZOJ 5110 Pollutant Control(边数最少最小割最小字典序输出)
描述 It's your first day in Quality Control at Merry Milk Makers, and already there's been a catastrop ...
- Codeforces 899F Letters Removing 线段树/树状数组
虽然每次给一个区间,但是可以看作在区间内进行数个点操作,同样数列下标是动态变化的,如果我们将每个字符出现看作1,被删除看作0,则通过统计前缀和就能轻松计算出两个端点的位置了!这正是经典的树状数组操作 ...
- Liferay 7:Liferay DXP全套教程内附源码
分享是美德 都是英文教程,有不明白的问题可以随时咨询我. http://www.javasavvy.com/liferay-7-hooks-tutorials/
- 威胁快报|首爆新型ibus蠕虫,利用热门漏洞疯狂挖矿牟利
一.背景 近日阿里云安全团队发现了一起利用多个流行漏洞传播的蠕虫事件.黑客首先利用ThinkPHP远程命令执行等多个热门漏洞控制大量主机,并将其中一台“肉鸡”作为蠕虫脚本的下载源.其余受控主机下载并运 ...
- Ubuntn16.04安装opencv3.1(特别注意环境变量)
参考:http://lib.csdn.net/article/opencv/25737: http://blog.csdn.net/yiranyhy/article/details/72935499: ...