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)的更多相关文章

  1. NOIp2018集训test-10-24(am&pm)

    李巨连续AK三场了,我跟南瓜打赌李巨连续AK七场,南瓜赌李巨连续AK五场. DAY1 T1 qu 按题意拿stack,queue和priority_que模拟即可.特判没有元素却要取出的情况. T2 ...

  2. NOIP2018 集训(三)

    A题 Tree 问题描述 给定一颗 \(n\) 个点的树,树边带权,试求一个排列 \(P\) ,使下式的值最大 \[\sum_{i=1}^{n-1} maxflow(P_i, P_{i+1}) \] ...

  3. NOIP2018 集训(二)

    A题 神炎皇 问题描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对 \((a,b)\) ,若满足 \(a+b\leq n\) 且 \(a+b\) 是 \(ab\) 的因子,则称 为神 ...

  4. NOIP2018 集训(一)

    A题 Simple 时间限制:1000ms | 空间限制:256MB 问题描述 对于给定正整数\(n,m\),我们称正整数\(c\)为好的,当且仅当存在非负整数\(x,y\)使得\(n×x+m×y=c ...

  5. NOIp2018集训test-10-18 (bike day4)

    这是一套简单题,这几天的考试让bike老爷感觉很绝望,说实话我也确实不知道还能怎么更简单了. 这几天的题换做llj.sxy应该都能轻松AK吧,至少随便考个250+应该不是问题吧,我越来越觉得觉得我跟他 ...

  6. NOIp2018集训test-10-17 (bike day3)

    发现自己gradully get moodier and moodier了 负面情绪爆发地越来越频繁,根本out of control,莫名其妙地就像着了魔一样 为什么用英语大概是因为今天早上早自习因 ...

  7. NOIp2018集训test-10-16 (bike day2)

    “毕姥爷:今天的题好简单啊,你们怎么考得这么烂啊,如果是noip你们就凉透了啊“ 今天的题难度应该是3.2.1递减的,但是我不知道哪根筋没搭对,平时我最多1h多就弃题了,今天硬生生写了2h20min的 ...

  8. [雅礼NOIP2018集训] day6

    打满暴力好像是一种挑战,已经连续几天考试最后一个小时自闭了,因为自以为打完了暴力,然而,结果往往差强人意 大概是考试的策略有些问题 T1: 我们设$g[x]$为在x时取小于等于m个物品的最大价值,下面 ...

  9. [雅礼NOIP2018集训 day4]

    感觉状态极差啊,今天居然爆零了 主要是以下原因: 1.又是T1看错题肝了两个小时,发现题意理解错误瞬间心态爆炸 2.T2交错了文件名 3.T3暴力子任务和正解(假的)混在一起,输出了两个答案 都想为自 ...

  10. [雅礼NOIP2018集训 day1]

    现在才来填坑,之后还要陆续补其他几天的,可能前几天真的太颓了 T1: 题目大意:给定一个长度为n的序列,m次询问每次询问给出l,r,询问区间l到r的元素在模k意义下的最大值 数据范围当然是你暴力写不过 ...

随机推荐

  1. vue 使用Better-Scroll

    注意点 1. 外层容器wrapper要设置高度,并且overflow:hidden. 2. wrapper里面的需要一个div包裹所有内容 3. 样式成功 4.  以上就是可以滚动的情况,wrappe ...

  2. spark代码写入hdfs错误

    报错: org.apache.hadoop.security.AccessControlException: Permission denied: user=hgm, access=WRITE 其实就 ...

  3. leetcood学习笔记-13

    错误记录 class Solution: def romanToInt(self, s: str) -> int: d = {'I':1,'V':5,'X':10,'L':50,'C':100, ...

  4. JMeter目录结构

    转载自https://www.cnblogs.com/imyalost/p/6959797.html 首先得了解一下这些东西,以后才能快速的找到某些配置文件进行修改(举个例子,改配置只是其中之一) 一 ...

  5. 线性dp——1197D

    一开始没有什么头绪,后来注意到m<=10,考虑是否可以用dp[i][j]表示第i位,前面跟了j个数的最大值 那么第i+1个数,直接和第i个数的[0,m]的m+1种状态去转移即可,如果是由0或m状 ...

  6. angulajs 详解 directive 中 的 scope 概念

    Directive 是 angularjs 中最重要的概念,我的理解就是自定义html tag, 这个自定的tag 浏览器不会解析,会有angularjs 来动态解析. 比如在html 中添加 < ...

  7. This inspection warns about local variables referenced before assignment.

    关于 local variable 'has' referenced before assignment 问题 今天在django开发时,访问页面总是出现错误提示“local variable 'ha ...

  8. Idea 导入项目不能运行

    1.项目结构里面配置sdk,配置output输出目录 2.配置语言等级 配置src源文件目录 配置目录里面添加application,添加main class

  9. 3、第一个Appium测试

    运行脚本前环境准备: 1.IDE,推荐使用IJ 2.安装jdk环境,推荐>1.8 3.准备一台真机或者模拟器 4.SDK 5.maven环境 项目目录: CalculatorTest.java文 ...

  10. 2019秋Java课程总结&实验总结一

    1.打印输出所有的"水仙花数",所谓"水仙花数"是指一个3位数,其中各位数字立方和等于该数本身.例如,153是一个"水仙花数". 实验源码: ...