NOIp2018集训test-9-6(am)
Problem A. divisor
发现x为k可表达一定可以表示成这种形式,如k=3,x=(1/3+1/2+1/6)x。
于是可以搜索k(k<=7)个1/i加起来等于1的情况,如果一个数是这些i的lcm的倍数这个数就是k可表达的。
std并没有给出它的搜索程序,我的搜索写得很不优秀,所以我写搜索写了很久。
一是用double会炸精度,于是我手写了分数类。
然后是搜的时候按从大到小搜,每次会有一个上限。
这样爆搜的话可以搜出6的,要搜出7的的话,因为实际上搜的是lcm,记录一下出现过的lcm,如果中途出现了这个lcm就直接return,。每次搜的时候是从up到dn搜的,一开始我在想要让lcm小的先出现应该先搜小的啊,李巨告诉我,先搜小的会让后面的up变得很大,而先搜大的,最开始的up也就7,后面的up也被限制得比较小,能先跑出较小的lcm,让这个优化有用。
这样对于每个k能搜出一些数,如果是这些数的倍数就可以k表达,这一步李巨直接ycl打表法代替,打出k表达数,从小到达一个一个把剩下的的倍数删除直到删完所有数,吊打爆搜。
这样就可以容斥做了,如果直接容斥最大的个数有15会炸,发现一些数的乘积是重复出现的,预处理出所有不同的数前面的容斥系数,不同的最多好像是300多个,就可以过这道题了。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=1e6+;
typedef long long LL;
typedef double db;
using namespace std;
int K,tot,tt[N],no[N],pp[N]; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} LL gcd(LL a,LL b) { return !b?a:gcd(b,a%b); }
LL lcm(LL a,LL b) { return a*b/gcd(a,b); } struct fs {
LL up,dn;
fs(LL up,LL dn):up(up),dn(dn){}
friend fs operator +(const fs&A,const fs&B) {
LL up=A.up*B.dn+A.dn*B.up,dn=A.dn*B.dn;
LL d=gcd(up,dn);
return fs(up/d,dn/d);
}
friend fs operator -(const fs&A,const fs&B) {
LL up=A.up*B.dn-A.dn*B.up,dn=A.dn*B.dn;
LL d=gcd(up,dn);
return fs(up/d,dn/d);
}
}; int tmp;
int a[],mx;
map<int,int>mp;
void dfs(int pos,int pr,fs now,LL nl) {
if(pos==K+) {
if(now.up==now.dn) {
//For(i,1,pos-1) printf("%d ",a[i]);
//puts("");
tt[++tot]=nl;
mp[nl]=;
}
return ;
}
if(now.up>=now.dn) return;
if(mp[nl]) return ;
fs tp=fs(,)-now;
int up=tp.dn*(K-pos+)/tp.up;
for(int i=up;i>=pr;i--) {
tp=now+fs(K-pos+,i);
if(tp.up<tp.dn) break;
a[pos]=i;
dfs(pos+,i,now+fs(,i),lcm(nl,i));
}
} int main() {
#ifdef ANS
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
read(K);
dfs(,,fs(,),);
cout<<tmp<<endl;
sort(tt+,tt+tot+);
int ans=;
For(i,,tot) if(!no[i]) {
For(j,i+,tot) if(tt[j]%tt[i]==) no[j]=;
pp[++ans]=tt[i];
}
cout<<ans<<endl;
For(i,,ans) cout<<pp[i]<<" ";
puts("");
Formylove;
}
打表
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
typedef long long LL;
typedef double db;
using namespace std;
int T;
LL A,B,K;
LL bs[][]={{},{},
{,},
{,,},
{,,,},
{,,,,,,},
{,,,,,,},
{,,,,,,,,,,,,,,,},
}; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} LL gcd(LL a,LL b) { return !b?a:gcd(b,a%b); }
LL lcm(LL a,LL b) { return a*b/gcd(a,b); } LL rc[][][];
int tot,tt[];
map<LL,int>mp;
void pre() {
For(id,,) {
int up=(<<bs[id][])-;
tot=; mp.clear();
For(i,,up) {
LL l=; int cc=;
For(j,,bs[id][]) if(i&(<<(j-)))
l=lcm(l,bs[id][j]),cc++;
if(mp[l]) ;
else mp[l]=++tot;
int x=mp[l];
rc[id][x][]=l;
rc[id][x][]+=((cc&)?:-);
}
tt[id]=tot;
}
} LL solve(LL n,int K) {
if(!n) return ;
LL rs=;
For(i,,tt[K])
rs+=n/rc[K][i][]*rc[K][i][];
return rs;
} #define ANS
int main() {
#ifdef ANS
freopen("divisor.in","r",stdin);
freopen("divisor.out","w",stdout);
#endif
read(T);
pre();
while(T--) {
read(A); read(B); read(K);
printf("%lld\n",solve(B,K)-solve(A-,K));
}
Formylove;
}
Problem B. rabbit
容易建出最大流模型,s向每堆胡萝卜连mi的边,每堆干草向t连ni的边,每堆胡萝卜向每堆干草连1的边。
根据最大流最小割定理,答案就是这个图的最小割,发现这个图的最小割可以表示成,s和胡萝卜的边中选a条边权和为Sa割掉,t和干草的边中选b条边权和为Sb的割掉,中间再割掉(n-a)*(m-b)条边。
ans=Sa+Sb+(n-a)*(m-b)
展开
ans=n*m+Sa-a*m+Sb-b*n+a*b
把权值全放到每条边上,a中的边权本为w的边权就是w-m,b中的边权本为w的边权就是w-n+a,最后的常数n*m不用管。
那么枚举a中选多少条边,按边权排序后选最小的那么多条,再选对于的b边权中小于0的那一部分。具体可以看看代码。
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int up=3e6+;
typedef long long LL;
typedef double db;
using namespace std;
int mm[up],nn[up],cntm[up],cntn[up];
LL sm[up],sn[up],M,N,m0,md,n0,nd,ans;; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} priority_queue<int>que; #define ANS
int main() {
#ifdef ANS
freopen("rabbit.in","r",stdin);
freopen("rabbit.out","w",stdout);
#endif
read(M); read(N);
read(m0); read(md); mm[m0]++; cntm[m0]++; sm[m0]+=m0;
read(n0); read(nd); nn[n0]++; cntn[n0]++; sn[n0]+=n0;
For(i,,M-) { m0=((LL)m0*+md)%(N+); mm[m0]++; cntm[m0]++; sm[m0]+=m0; }
For(i,,N-) { n0=((LL)n0*+nd)%(M+); nn[n0]++; cntn[n0]++; sn[n0]+=n0; }
M-=cntm[]; N-=cntn[];
cntm[]=mm[]=cntn[]=nn[]=;
For(i,,N) cntm[i]+=cntm[i-],sm[i]+=sm[i-];
For(i,,M) cntn[i]+=cntn[i-],sn[i]+=sn[i-];
ans=1e18;
For(i,,N) {
For(j,,mm[i]) {
LL a=cntm[i]-j;
LL b=cntn[M-a];
LL tp=N*M+sm[i]-(LL)j*i-a*N+sn[M-a]-M*b+a*b;
ans=min(ans,tp);
}
}
printf("%lld\n",ans);
Formylove;
}
/*
6 4
1 1 3 3 2 2
5 4 4 4
*/
Problem C. drinks
什么神题(解),不会。
NOIp2018集训test-9-6(am)的更多相关文章
- NOIp2018集训test-10-24(am&pm)
李巨连续AK三场了,我跟南瓜打赌李巨连续AK七场,南瓜赌李巨连续AK五场. DAY1 T1 qu 按题意拿stack,queue和priority_que模拟即可.特判没有元素却要取出的情况. T2 ...
- NOIP2018 集训(三)
A题 Tree 问题描述 给定一颗 \(n\) 个点的树,树边带权,试求一个排列 \(P\) ,使下式的值最大 \[\sum_{i=1}^{n-1} maxflow(P_i, P_{i+1}) \] ...
- NOIP2018 集训(二)
A题 神炎皇 问题描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对 \((a,b)\) ,若满足 \(a+b\leq n\) 且 \(a+b\) 是 \(ab\) 的因子,则称 为神 ...
- NOIP2018 集训(一)
A题 Simple 时间限制:1000ms | 空间限制:256MB 问题描述 对于给定正整数\(n,m\),我们称正整数\(c\)为好的,当且仅当存在非负整数\(x,y\)使得\(n×x+m×y=c ...
- NOIp2018集训test-10-18 (bike day4)
这是一套简单题,这几天的考试让bike老爷感觉很绝望,说实话我也确实不知道还能怎么更简单了. 这几天的题换做llj.sxy应该都能轻松AK吧,至少随便考个250+应该不是问题吧,我越来越觉得觉得我跟他 ...
- NOIp2018集训test-10-17 (bike day3)
发现自己gradully get moodier and moodier了 负面情绪爆发地越来越频繁,根本out of control,莫名其妙地就像着了魔一样 为什么用英语大概是因为今天早上早自习因 ...
- NOIp2018集训test-10-16 (bike day2)
“毕姥爷:今天的题好简单啊,你们怎么考得这么烂啊,如果是noip你们就凉透了啊“ 今天的题难度应该是3.2.1递减的,但是我不知道哪根筋没搭对,平时我最多1h多就弃题了,今天硬生生写了2h20min的 ...
- [雅礼NOIP2018集训] day6
打满暴力好像是一种挑战,已经连续几天考试最后一个小时自闭了,因为自以为打完了暴力,然而,结果往往差强人意 大概是考试的策略有些问题 T1: 我们设$g[x]$为在x时取小于等于m个物品的最大价值,下面 ...
- [雅礼NOIP2018集训 day4]
感觉状态极差啊,今天居然爆零了 主要是以下原因: 1.又是T1看错题肝了两个小时,发现题意理解错误瞬间心态爆炸 2.T2交错了文件名 3.T3暴力子任务和正解(假的)混在一起,输出了两个答案 都想为自 ...
- [雅礼NOIP2018集训 day1]
现在才来填坑,之后还要陆续补其他几天的,可能前几天真的太颓了 T1: 题目大意:给定一个长度为n的序列,m次询问每次询问给出l,r,询问区间l到r的元素在模k意义下的最大值 数据范围当然是你暴力写不过 ...
随机推荐
- 2、Python 基础类型 -- String 字符串类型
字符串常用的方法: 1.分割:string.split(str="", num=string.count(str)) 以 str 为分隔符切片 string,如果 num 有指 ...
- oracle查询重复数据出现次数
话不多数上代码: 我在Oracle数据库查数据,发现重复数据,于是我想把重复条数以及具体数据查出来: 下面是数据 然后我需要知道重复多少条 (重复十条,也就是有五条数据相同) SQL: select ...
- git——修改已经提交并push后的commit注释
把代码push到远程后,发现commit的注释居然多了几个错别字,不行,必须改了! 搜索了一些答案之后自己做了一个总结如下: ①修改倒数第次的commit 指令:$ git rebase -i HEA ...
- 使用springBoot和mybatis整合时出现如下错误:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)解决方案
在pom.xml文件中添加如下: <build> <resources> <resource> & ...
- JXOI2017 加法
题目描述: 可怜有一个长度为 \(n\) 的正整数序列 \(A\),但是她觉得 \(A\) 中的数字太小了,这让她很不开心. 于是她选择了 \(m\) 个区间 \([l_i, r_i]\) 和两个正整 ...
- flutter 卡在Running Gradle task 'assembleDebug'...
Android项目运行时出错 卡在Initializing gradle… 运行时会卡在Initializing gradle..., 此时因为Android项目会用到Gradle, 如果没有FQ,下 ...
- 拾遗:Go 代码结构
#define @ $ 概述 Go 编码通常将所有代码放置在同一个工作区 一个工作区包含多个版本仓库,使用 Git 等工具控制 每个仓库包含一个或多个包 每个包由同一目录中的一份或多份源代码组成 包的 ...
- 深入浅出原生JS:One
Arguments 对象: 在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们. 例如,在函数 sayHi() 中,第一个参数是 message.用 argumen ...
- locust性能测试框架随笔
现在有很多的性能测试工具,比如说我们熟悉的loadrunner.jmeter.ab.webbench等等,这些工具如果对一个没用过的朋友来说,学习起来比较不容易,但是如果你能看懂python代码,会写 ...
- Size Assert
判断返回内容的大小