https://vjudge.net/contest/173277#overview

A.平方差公式后变为 n = (x + y)(x - y)

令 t = x - y ,变成

n = (t + 2x) * t,要 x 最小

O(sqrt(n)) 枚举 n 的因数即可

 #include <cstdio>

 typedef long long ll;

 ll n, m, k, t;

 int main() {
scanf("%lld", &n);
while(n --) {
k = ;
scanf("%lld", &m);
for(ll i = ;i * i < m;i ++) {
if((m % i == ) && ((m / i - i) % == ) ) {
t = (m / i - i) / ;
k = ;
}
}
if(!k) puts("-1");
else printf("%lld\n", t);
}
return ;
}

B.

C.如果GCD中间是加号会困难很多

乘号的话,我们枚举质数对ans的贡献即可

质数 pi 对结果的贡献就是

pow(pi,(n/pi)*(m/pi) + (n/pi^2)*(m/pi^2) + (n/pi^3)*(m/pi^3) +... )

最坏效率,1kw质数大约 n / ln(n) 个

pi = 2, 计算贡献需要logn次,快速幂约logn

复杂度约为 O(n / ln(n) * logn),考虑到后面质数变大

pi > 100时, 计算贡献就只有3次了

实际计算贡献和快速幂平均下来不到2次

所以 n = 1kw 时是O(n)级别的

 #include <cstdio>
#include <algorithm> using std::swap; typedef long long ll; int p[], v[]; int tt; long long n, m, ans; const int Mod = 1e9 + ; ll calc(ll x, ll k) {
ll res = ;
for(;k > ;x = x * x % Mod, k >>= )
if(k & ) res = res * x % Mod;
return res;
} int main() {
for(int i = ;i <= ;i ++) {
if(!v[i]) p[++ p[]] = i;
for(int j = ;j <= p[] && 1ll * i * p[j] <= ;j ++) {
v[i * p[j]] = ;
if(i % p[j] == ) break;
}
}
long long t, cnt;
scanf("%d", &tt);
while(tt --) {
ans = ;
scanf("%lld %lld", &n, &m);
if(m > n) swap(n, m);
for(int i = ;p[i] <= m && i <= p[];i ++) {
t = p[i], cnt = ;
while() {
cnt += (n / t) * (m / t);
if(m / t >= p[i]) t *= p[i];
else break;
}
ans = ans * calc(p[i], cnt) % Mod;
}
printf("%lld\n", ans);
}
return ;
}

D.这个题今年3月刚写的又忘记了...

我们一个想法是分解质因数

得到 n! 里每个质数出现的最少次数

但我们平时分解质因数都是O(sqrt(n))的

即使使用前缀和,10^7也无法O(n^1.5)分解

所以这里用了一个巧妙又优秀的的O(nlogn)处理方法

 for(int i = ;i * i <= m;i ++) {
if(v[i]) continue;
for(int j = i * i;j <= m;j += i)
v[j] = -i;
}
for(int i = ;i <= m;i ++) {
int j = i;
while() {
if(v[j] >= ) {
cout << j << endl;
break;
}
else cout << -v[j] << endl, j /= -v[j];
}
}

当 i 为非质数时, -vis[i] 存的是 i 的最大的不大于sqrt(i)的质因数

分解质因数后可以二分

也可以用每个质数出现的个数得到不等式 n >= ci

实际效率约均为O(n)级别,前者思考复杂度低

 #include <bits/stdc++.h>

 #define rep(i, j, k) for(int i = j;i <= k;i ++)
#define rev(i, j, k) for(int i = j;i >= k;i --) using namespace std; typedef long long ll; const int maxn = ; int n, m, a[maxn], b[maxn], p[maxn]; int v[maxn], num[maxn]; ll cnt[maxn]; bool judge(ll x) {
ll y, c;
rep(i, , p[]) {
y = x, c = ;
while(y) y /= p[i], c += y;
if(c < cnt[i]) return ;
}
return ;
} int main() {
ios::sync_with_stdio(false);
cin >> n;
rep(i, , n) {
cin >> a[i];
m = max(m, a[i]);
b[a[i]] ++;
}
for(int i = ;i * i <= m;i ++) {
if(v[i]) continue;
for(int j = i * i;j <= m;j += i)
v[j] = -i;
}
rep(i, , m)
if(!v[i])
p[++ p[]] = i, num[i] = p[];
rev(i, m, )
b[i] += b[i + ];
rep(i, , m) {
int j = i;
while() {
if(v[j] >= ) {
cnt[num[j]] += b[i];
break;
}
else cnt[num[-v[j]]] += b[i], j /= -v[j];
}
}
ll l = , r = 10000000000000ll, mid, ans;
while(l <= r) {
mid = (l + r) >> ;
if(judge(mid)) ans = mid, r = mid - ;
else l = mid + ;
}
cout << ans;
return ;
}

E.利用欧拉函数的性质,对于给定的 x

满足 phi[n] >= x 的最小的 n 一定是个质数

范围不大预处理即可

 #include <cstdio>

 const int maxn = ;

 int pr[maxn], ph[maxn], vis[maxn];

 int Case, n, a, b[maxn];

 long long ans;

 int main() {
for(int i = ;i < maxn;i ++) {
if(!vis[i]) {
pr[++ pr[]] = i;
ph[i] = i - ;
}
for(int j = ;j <= pr[] && i * pr[j] < maxn;j ++) {
vis[i * pr[j]] = ;
if(i % pr[j] == ) break;
}
}
int last = ;
for(int i = ;i;i --) {
b[i] = last;
if(ph[i]) last = i;
}
scanf("%d", &Case);
for(int t = ;t <= Case;t ++) {
ans = ;
scanf("%d", &n);
for(int j = ;j <= n;j ++) {
scanf("%d", &a);
ans += b[a];
}
printf("Case %d: %lld Xukha\n", t, ans);
}
return ;
}

F.

G.求前几位的题目,取个对数就行

利用斐波那契数列的通项公式

我们发现后面减去的一项<1,n变大之后忽略即可

取完对数乘法变加法

最后输出前4位,必须舍去后面位数所以直接double转int

%.0f 会四舍五入并不满足要求

 #include <cstdio>
#include <cmath>
#include <algorithm> using std::abs; int n, f[]; int main() {
f[] = ;
for(int i = ;i < ;i ++) f[i] = f[i - ] + f[i - ];
while(scanf("%d", &n) != EOF) {
if(n < ) printf("%d\n", f[n] % );
else {
double x = (log( / sqrt(5.0)) + log((sqrt(5.0) + ) / ) * n) / log(10.0);
x -= (int)x;
x = pow(, x);
while(x < ) x *= ;
printf("%d\n", (int)x);
}
}
return ;
}

H.

I.混进来的放水题目

可以先把每一层节点都挂到上一层的一个节点上

可以出现最多的叶子节点

如果发现太多了就开始把当前层的节点

往上一层的其他节点上挪动,每动一次减少一个叶子节点

 #include <cstdio>

 const int maxn = ;

 int n, t, k, b[maxn], s[maxn], a[maxn];

 int main() {
s[] = , s[] = ;
scanf("%d %d %d", &n, &t, &k);
if(k > n - t) {
puts("-1");
return ;
}
for(int j = ,i = ;i <= t;i ++) {
scanf("%d", &a[i]), s[i + ] = a[i] + s[i];
for(int p = ;p <= a[i];p ++, j ++)
b[j] = s[i - ];
}
k = n - t - k;
if(k > ) {
for(int p = ;p <= t;p ++) {
for(int j = s[p - ] + , i = s[p] + ;i < s[p + ] && j < s[p];i ++, j ++) {
b[i] = j, k --;
if(!k) break;
}
if(!k) break;
}
}
if(k) puts("-1");
else {
printf("%d\n", n);
for(int i = ;i <= n;i ++)
printf("%d %d\n", i, b[i]);
}
}

J.快速幂水题

另外因为2009非质数,所以不到50的时候ans已经变成0了

 #include <cstdio>

 typedef long long ll;

 ll n, a[];

 ll power(ll x, ll k) {
ll res = ;
for(;k;k >>= , x = x * x % )
if(k & ) res = res * x % ;
return res;
} int main() {
ll m, ans;
a[] = , a[] = ;
for(int i = ;i < ;i ++)
a[i] = a[i - ] * i % ;
while(scanf("%lld", &n) != EOF) {
ans = ;
m = n / ;
ans *= power(a[], m);
printf("%lld\n", ans * a[n % ] % );
}
return ;
}

bupt summer training for 16 #4 ——数论的更多相关文章

  1. bupt summer training for 16 #8 ——字符串处理

    https://vjudge.net/contest/175596#overview A.设第i次出现的位置左右端点分别为Li,Ri 初始化L0 = 0,则有ans = sum{ (L[i] - L[ ...

  2. bupt summer training for 16 #7 ——搜索与DP

    https://vjudge.net/contest/174962#overview A.我们发现重点在于x,y只要累加就ok了 在每个x上只有上下两种状态,所以可以记忆化搜索 f[0/1][i]表示 ...

  3. bupt summer training for 16 #6 ——图论

    https://vjudge.net/contest/174020 A.100条双向边,每个点最少连2个边 所以最多100个点,点的标号需要离散化 然后要求恰好经过n条路径 快速幂,乘法过程就是flo ...

  4. bupt summer training for 16 #5 ——数据结构

    https://vjudge.net/contest/173780 A.假设 Pt = i,则由Ppi = i得 Ppt = t = Pi 所以就有 if Pt = i then Pi = t #in ...

  5. bupt summer training for 16 #3 ——构造

    https://vjudge.net/contest/172464 后来补题发现这场做的可真他妈傻逼 A.签到傻逼题,自己分情况 #include <cstdio> #include &l ...

  6. bupt summer training for 16 #2 ——计算几何

    https://vjudge.net/contest/171368#overview A.一个签到题,用叉积来判断一个点在一条线的哪个方向 可以二分,数据范围允许暴力 #include <cst ...

  7. bupt summer training for 16 #1 ——简单题目

    D.What a Mess 给n个数,求其中能满足 a[i] % a[j] == 0 的数对之和 n = 1W,max_ai = 100W 不是很大,所以就直接筛就可以了 计算可得最高复杂度 < ...

  8. 【Android Developers Training】 16. 暂停和恢复一个Activity

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. 【Android Developers Training】 14. 序言:管理Activity生命周期

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

随机推荐

  1. SuperSocket中的Server是如何初Start的

    第一个函数 d:\sourcecode\github\supersocket\quickstart\basic\telnetserver_startbyconfig\program.cs static ...

  2. YTU 2705:用重载求距离

    2705: 用重载求距离. 时间限制: 1 Sec  内存限制: 128 MB 提交: 208  解决: 114 题目描述 使用函数重载的方法定义两个重名函数,分别求出整型数的两点间距离和浮点型数的两 ...

  3. java使用poi读取doc和docx文件(maven自动导入依赖包)

    java使用poi读取doc和docx文件(maven自动导入依赖包) 于是在网上搜寻了一阵之后才发现原来doc文档和excel一样不能用普通的io流的方法来读取,而是也需要用poi,于是进行了一番尝 ...

  4. POJ2449 Remmarguts' Date 第K短路

    POJ2449 比较裸的K短路问题 K短路听起来高大上 实际思路并不复杂 首先对终点t到其他所有点求最短路 即为dist[] 然后由起点s 根据当前走过的距离+dist[]进行A*搜索 第k次到达t即 ...

  5. 创建APP检查更新页

    本文来源及参考:Create a check for updates page for your app. 这篇文章解释了如何创建一个简单的检查更新页,检查该用户已安装的应用程序的最新版本. 简介 这 ...

  6. PCB 内层负片散热PAD Symbols尺寸更改方法

    如下图这是我们熟悉的内层负片散热PAD Symbols,我们CAM制作时,为了满足PCB工厂生产制作能力,,会优化散热PAD尺寸,让热PAD的尺寸符合制作规范要求,通常我们只关注散热PAD的3个指标即 ...

  7. B-Tree 漫谈 (从二叉树到二叉搜索树到平衡树到红黑树到B树到B+树到B*树)

    关于B树的学习还是需要做点笔记. B树是为磁盘或者其他直接存取辅助存储设备而设计的一种平衡查找树.B树与红黑树的不同在于,B树可以有很多子女,从几个到几千个.比如一个分支因子为1001,高度为2的B树 ...

  8. Zookeeper概念学习系列之zookeeper的节点

    znode有两种类型:  临时节点(ephemeral  node) 和 持久节点(persistent node). znode的类型在创建时确定并且之后不能再修改. 短暂znode的客户端会话结束 ...

  9. RabbitMQ~消费者实时与消息服务器保持通话

    这个文章主要介绍简单的消费者的实现,rabbitMQ实现的消费者可以对消息服务器进行实时监听,当有消息(生产者把消息推到服务器上之后),消费者可以自动去消费它,这通常是开启一个进程去维护这个对话,它与 ...

  10. MVC系列学习(三)-EF的延迟加载

    1.什么叫延迟加载 字面上可以理解为,一个动作本该立即执行的动作,没有立即执行 2.从代码上理解 static void Main(string[] args) { //执行该语句的时候,查看sql监 ...