当前位置: 首页 > news >正文

nflsoi 8.16 题解

数论场,难调场,评测机崩溃场,复活场。

C.#12322 幂次整除 / TopCoder 12870 BigFatInteger2

题意

给定四个整数 a,b,c,da,b,c,da,b,c,d,判断 aba^bab 是否为 cdc^dcd 的倍数,是输出 divisible,否则输出 not divisible

A,B,C,D∈[1,109]A,B,C,D\in[1,10^9]A,B,C,D[1,109]

思路

就是这题害得 20035 崩溃。

这题值域太大,预处理质数肯定超时,所以宁愿 O(V)O(\sqrt{V})O(V) 在线判断,顶多减少判断次数。

先特判:

  • 对于 111 的情况,c=1c=1c=1 可以,a=1a=1a=1c>1c>1c>1 不行;
  • 幂次相等的情况,a<ca<ca<c 不行;
  • a,c>1a,c>1a,c>1,两数互质不行;
  • g=gcd⁡(a,c)g=\gcd(a,c)g=gcd(a,c),对于 ccc 的剩余因子 c/gc/gc/g,如果 gcd⁡(a,c/g)=1\gcd(a,c/g)=1gcd(a,c/g)=1,即 ccc 存在 aaa 没有的质因子,就不行。

接下来就是分解质因数和幂次,然后判断相同质因子 aaa 的幂次和是否大于 ccc 的即可。

其实这题不难,但是测评太久了,而且容易错,搞人心态。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sayno {puts("not divisible");return 0;}
#define sayes {puts("divisible");return 0;}
const ll N=1e6+9;
ll a,b,c,d;
ll g;
ll f1[N],f2[N],k1[N],k2[N],c1,c2;
bool isprime(ll x)
{for(int i=2;i*i<=x;i++)if(x%i==0)return 0;return 1;
}
int main()
{scanf("%lld%lld%lld%lld",&a,&b,&c,&d);if(c==1)sayesif(a==1&&c>1)saynoif(b==d&&a<c)saynoll g=__gcd(a,c);if(g==1)saynoll A=a/g,C=c/g;if(C>1&&__gcd(a,C)==1)saynofor(ll i=2;a>1;i++){if(isprime(a)){f1[++c1]=a;k1[c1]=1;break;}ll tot=0;while(a%i==0){tot++;a/=i;}if(tot)f1[++c1]=i,k1[c1]=tot;}for(ll i=2;c>1;i++){if(isprime(c)){f2[++c2]=c;k2[c2]=1;break;}ll tot=0;while(c%i==0){tot++;c/=i;}if(tot)f2[++c2]=i,k2[c2]=tot;}if(c1<c2)saynoll pos=1;for(int i=1;i<=c2;i++){while(pos<=c1&&f1[pos]<f2[i])pos++;if(f1[pos]!=f2[i])saynoif(k1[pos]*b<k2[i]*d)sayno}sayesreturn 0;
}
/*
75 
1
5 
2
*/

D.#16983 完整正方形 / AT_abc311_e Defect-free Squares

题意

有一个高为 HHH 行、宽为 WWW 列的网格。网格中从上往下第 iii 行、从左往右第 jjj 列的格子记作 (i,j)(i, j)(i,j)
网格中的每个格子要么有洞,要么没有洞。恰好有 NNN 个格子有洞,这些格子的位置分别为 (a1,b1),(a2,b2),…,(aN,bN)(a_1, b_1), (a_2, b_2), \dots, (a_N, b_N)(a1,b1),(a2,b2),,(aN,bN)

当正整数三元组 (i,j,n)(i, j, n)(i,j,n) 满足以下条件时,以 (i,j)(i, j)(i,j) 为左上角、(i+n−1,j+n−1)(i + n - 1, j + n - 1)(i+n1,j+n1) 为右下角的正方形区域被称为没有洞的正方形

  • i+n−1≤Hi + n - 1 \leq Hi+n1H
  • j+n−1≤Wj + n - 1 \leq Wj+n1W
  • 对于所有满足 0≤k≤n−1,0≤l≤n−10 \leq k \leq n - 1, 0 \leq l \leq n - 10kn1,0ln1 的非负整数对 (k,l)(k, l)(k,l)(i+k,j+l)(i + k, j + l)(i+k,j+l) 这个格子没有洞。

请问网格中一共有多少个没有洞的正方形?

1≤H,W≤30001 \leq H, W \leq 30001H,W30000≤N≤min⁡(H×W,105)0 \leq N \leq \min(H \times W, 10^5)0Nmin(H×W,105)(ai,bi)(a_i, b_i)(ai,bi) 互不相同。

思路

看到这题单调栈应激了,怎么跟这题还在同一场 abc?

考虑枚举 (i,j)(i,j)(i,j) 为右下角,有多少个正方形。想要悬线法吗?想要单调栈吗?怎么确定 min⁡(Li,j,upi,j)\min(L_{i,j},up_{i,j})min(Li,j,upi,j) 边长的正方形里面没有洞呢?

还是 dp 吧,其实也不难想。设 fi,jf_{i,j}fi,j 表示以 (i,j)(i,j)(i,j) 为右下角的正方形有多少个。我们并入 i−1i-1i1 行或者 j−1j-1j1 列的信息,正方形的个数也就多出一个,因此是这其中某一个 +1+1+1

怎么处理洞呢?首先如果 (i,j)(i,j)(i,j) 有洞那么 fi,j=0f_{i,j}=0fi,j=0,假若从 (i,j)(i,j)(i,j)(i+1,j)(i+1,j)(i+1,j) 转移,因为 (i+1,j)(i+1,j)(i+1,j) 上面有个洞,所以不管左上状态 fi−1,jf_{i-1,j}fi1,j 和左侧状态 fi,j−1f_{i,j-1}fi,j1 状态有多大,(i,j)(i,j)(i,j) 为右下角的合法正方形边长只能为 111

因此有洞的点相当于给转移搞了个上界,即转移到 fi,jf_{i,j}fi,j 是要在 fi,j−1,fi−1,j,fi−1,j−1f_{i,j-1},f_{i-1,j},f_{i-1,j-1}fi,j1,fi1,j,fi1,j1 中找一个最小的上界来转移,即:
fi,j=min⁡(fi,j−1,fi−1,j,fi−1,j−1)+1f_{i,j}=\min(f_{i,j-1},f_{i-1,j},f_{i-1,j-1})+1fi,j=min(fi,j1,fi1,j,fi1,j1)+1

答案即 ∑fi,j\sum f_{i,j}fi,j

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=3004,M=1e5+9;
ll h,w,n;
bool vis[N][N];
ll f[N][N];
int main()
{scanf("%lld%lld%lld",&h,&w,&n);for(int i=1;i<=n;i++){ll x,y;scanf("%lld%lld",&x,&y);vis[x][y]=1;}ll ans=0;for(int i=1;i<=h;i++){for(int j=1;j<=w;j++){if(vis[i][j])f[i][j]=0;//断左断上 else f[i][j]=min(f[i-1][j-1],min(f[i-1][j],f[i][j-1]))+1;ans+=f[i][j];}}printf("%lld",ans);return 0;
}

E.#25020 偏移量 / CF1152C Neko does Maths

题意

Neko 有两个整数 aaabbb。他的目标是找到一个 k≥0k\ge 0k0,使得 a+ka+ka+kb+kb+kb+k 的最小公倍数尽可能小。如果有多个最优的 kkk,他需要选择最小的那个。

1≤a,b≤1091\le a,b\le 10^91a,b109

思路

带个 kkklcm(a+k,b+k)=(a+k)(b+k)gcd⁡(a+k,b+k)\mathrm{lcm}(a+k,b+k)=\dfrac{(a+k)(b+k)}{\gcd(a+k,b+k)}lcm(a+k,b+k)=gcd(a+k,b+k)(a+k)(b+k) 很麻烦,但是如果我辗转相除呢?

考虑求 gcd⁡(a+k,b−a)\gcd(a+k,b-a)gcd(a+k,ba)(钦定 a<ba<ba<b),此时 b−ab-aba 为定值而且因数只能在其因数里取到。枚举一个因数 xxx,那么存在一个合法的 kkkk=x−amodxk=x-a\bmod xk=xamodx 使 a+ka+ka+k 成为 xxx 的倍数。此时判断 gcd⁡(a+k,b+k)\gcd(a+k,b+k)gcd(a+k,b+k) 是否恰为 xxx,以及其 lcm\mathrm{lcm}lcm 是否能取得更小即可。时间复杂度 O(b−alog⁡V)O(\sqrt{b-a}\log V)O(balogV)log⁡V\log VlogV 约为做 gcd⁡\gcdgcd 的值域。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll inf=3e14;
ll a,b;
ll cha;
ll cal(ll a,ll b,ll k,ll d)
{return (a+k)/d*(b+k);
}
int main()
{scanf("%lld%lld",&a,&b);if(a>b)swap(a,b);cha=b-a;ll ans=0,mi=a*b/__gcd(a,b);for(int i=1;i*i<=cha;i++){if(cha%i==0){ll x=i,y=cha/i;ll k=x-a%x;if(__gcd(a+k,b+k)==x){if(cal(a,b,k,x)<mi){mi=cal(a,b,k,x);ans=k;}}if(x==y)continue;k=y-a%y;if(__gcd(a+k,b+k)==y){if(cal(a,b,k,y)<mi){mi=cal(a,b,k,y);ans=k;}}}}printf("%lld",ans);return 0;
}

F.#8429 小学数学 / BZOJ4429 Nwerc2015 Elementary Math 小学数学

题意

Ellen 正在教她的学生小学数学,期末考试的时间到了。考试包含n道题目,每道题要求学生对一对数字进行加(+)、减(-)或乘(*)运算。

Ellen已经选好了 nnn 对数 (a,b)(a,b)(a,b),现在需要为每对数决定应该使用哪种运算。为了避免学生感到厌烦,Ellen希望确保这n道题的正确答案都不相同。

请帮助Ellen自动完成考试的构建工作。你可以输出任意一个。如果没有有效答案,则输出一行字符串"impossible"。

输出的运算符前后都有空格,1≤n≤25001\le n\le 25001n2500∣a∣,∣b∣≤106|a|,|b|\le 10^6a,b106

思路

数对进行三种运算会有三种运算结果,不同的数对经过不同的运算可能会有相同的结果,我们需要这些结果不相同,即 nnn 个数对能够恰好配对若干个结果。

这不就是二分图匹配吗?把结果离散化成点然后跑匈牙利算法去匹配即可。

(说着容易,实则不算难调,但是题目卡我输出格式、不能分开输出数和符号什么意思?喜提 333 页提交记录)

代码

//BZOJ4429
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=5504;
ll n;
struct term
{ll x,y;ll add,minus,times;
}a[N];
map<ll,ll>mp;
vector<ll>G[N*5];
ll val[N*5],op[N*5];
bool vis[N*5];
ll match[N*5],pp[N];
bool dfs(ll u)
{for(auto v:G[u]){if(vis[v])continue;vis[v]=1;if(match[v]==0||dfs(match[v])){match[v]=u;pp[u]=v;return 1;}}return 0;
}
struct pout
{ll x,y,op,val,id;
}b[N*5];
bool cmp(pout x,pout y)
{return x.id<y.id;
}
ll vv[N*5],nv,nnv;
int main()
{scanf("%lld",&n);for(int i=1;i<=n;i++){ll x,y;scanf("%lld%lld",&x,&y);a[i]=(term){x,y,x+y,x-y,x*y};}ll pos=n;for(int i=1;i<=n;i++){//	cout<<i<<":"<<a[i].x<<" "<<a[i].y<<endl;//	cout<<a[i].add<<"\n"<<a[i].minus<<"\n"<<a[i].times<<"\n\n";if(!mp[a[i].add])mp[a[i].add]=++pos,val[pos]=a[i].add,op[pos]=1; if(!mp[a[i].minus])mp[a[i].minus]=++pos,val[pos]=a[i].minus,op[pos]=2;if(!mp[a[i].times])mp[a[i].times]=++pos,val[pos]=a[i].times,op[pos]=3;G[i].push_back(mp[a[i].add])/*,cout<<i<<"->"<<mp[a[i].add]<<"\n"*/;G[i].push_back(mp[a[i].minus])/*,cout<<i<<"->"<<mp[a[i].minus]<<"\n"*/;G[i].push_back(mp[a[i].times])/*,cout<<i<<"->"<<mp[a[i].times]<<"\n"*/;}ll cnt=0;for(int i=1;i<=n;i++){memset(vis,0,sizeof(vis));if(dfs(i))cnt++;else break;}if(cnt<n){puts("impossible");return 0;}for(int i=1;i<=n;i++){ll ret;char op;if(val[pp[i]]==a[i].add)op='+';if(val[pp[i]]==a[i].minus)op='-';if(val[pp[i]]==a[i].times)op='*';cout<<a[i].x<<" "<<op<<" "<<a[i].y<<" = "<<val[pp[i]]<<"\n";}return 0;
}
http://www.dtcms.com/a/334780.html

相关文章:

  • 【数据结构】-2- 泛型
  • Python - 100天从新手到大师:第十一天常用数据结构之字符串
  • Java实现汉诺塔问题
  • AI Agents 2025年十大战略科技趋势
  • 【嵌入式C语言】六
  • .net印刷线路板进销存PCB材料ERP财务软件库存贸易生产企业管理系统
  • mit6.824 2024spring Lab1 MapReduce
  • 衡石使用指南嵌入式场景实践之仪表盘嵌入
  • 3 统一建模语言(UML)(上)
  • 力扣 hot100 Day75
  • 动手学深度学习(pytorch版):第三章节—线性神经网络(6) softmax回归的从零开始实现
  • 基于深度学习的老照片修复系统
  • 嵌入式硬件篇---电源电路
  • SpringBoot自动配置原理(二)
  • 智能客服、AI工作流、语音、聊天模板
  • MySQL的下载安装(MSI和ZIP版本都有)
  • 【Kubernetes系列】Kubernetes 中 Pod 层参数与 Deployment 层 Env 参数的区别与级别分析
  • WSL中占用磁盘空间大问题解决
  • 自适应阈值二值化参数详解 ,计算机视觉,图片处理 邻域大小 调整常数(C=3)和可视化调节参数的应用程序
  • 区块链技术原理(14)-以太坊数据结构
  • ubuntu更新chrome版本
  • 我的世界Java版1.21.4的Fabric模组开发教程(十九)自定义生物群系
  • 力扣(LeetCode) ——622. 设计循环队列(C语言)
  • 《C语言程序设计》笔记p10
  • 如何拿捏unittest自动化测试框架?
  • 代码随想录算法训练营四十三天|图论part01
  • 同创物流学习记录2·电车
  • 【手撕JAVA多线程】1.从设计初衷去看JAVA的线程操作
  • 【C++】STL 容器—list 底层剖析
  • Java应届生求职八股(5)---并发编程篇