[补档]各种奇怪的韩信问题

这是两道奇怪的韩信问题

韩信点兵&丧心病狂的韩信大点兵

T1 [COGS 1786]韩信点兵

题目

  韩信是中国军事思想“谋战”派代表人物,被后人奉为“兵仙”、“战神”。“王侯将相”韩信一人全任。“国士无双”、“功高无二,略不世出”是楚汉之时人们对其的评价。作为统帅,他率军出陈仓、定三秦、擒魏、破代、灭赵、降燕、伐齐,直至垓下全歼楚军,无一败绩,天下莫敢与之相争。

  相传,韩信带兵打仗时,从不直接清点军队人数。有一次,韩信带1500名兵士打仗,战死四五百人。站3人一排,多出2人;站5人一排,多出4人;站7人一排,多出6人。韩信马上说出人数:1049。

  这次,刘邦派韩信带兵N人攻打一座重兵驻扎的城市。城市占领了,可汉军也是伤亡惨重。韩信需要知道汉军至少损失了多少兵力,好向刘邦汇报。

  已知韩信发出了M次命令,对于第i次命令,他选择一个素数Pi,要求士兵每Pi人站一排,此时最后一排剩下了ai人。你的任务是帮助韩信求出这种情况下汉军损失兵力的最小值。当然,由于士兵们都很疲惫,他们有可能站错队伍导致韩信得到的数据有误

INPUT

  第一行两个正整数N,M,分别代表最初的军队人数和韩信的询问次数。

  接下来有M行,每行两个非负整数Pi,ai,代表韩信选择的素数和此时剩下的人数。

  输入保证每个素数各不相同

OUTPUT

  输出一行,一个整数。

  若有解,输出最小损失人数。若无解,输出-1.

SAMPLE

INPUT

1500 3

3 2

5 4

7 6

OUTPUT

31

解题报告

  CRT裸题

  CRT:中国剩余定理(中国单身狗定理)

  设正整数m1,m2,...,mk两两互素,则同余方程组

    x≡a1 (mod m1)

    x≡a2 (mod m2)

    x≡a3 (mod m3)

     . . . . . .

    x≡ak (mod mk)

  有整数解,并且在模M=m1×m2×...×mk下的解是唯一的,解为

    x≡(a1×M1×ny(M1)+...+ak×Mk×ny(Mk))mod M

  其中Mi=M/mi,而ny(Mi)为Mi模mi的逆元

  代码如下:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 typedef long long L;
 6 L n;
 7 int m;
 8 L a[11],mod[11];
 9 L M(1),ans(0);
10 inline void extend_gcd(L a,L b,L &x,L &y){
11     if(b==0){
12         x=1;
13         y=0;
14         return;
15     }
16     extend_gcd(b,a%b,x,y);
17     L tmp(x);
18     x=y;
19     y=tmp-(a/b)*y;
20 }
21 inline L CRT(L a[],L m[],int n){
22     for(int i=1;i<=n;i++)
23         M*=m[i];
24     for(int i=1;i<=n;i++){
25         L x,y;
26         L Mi(M/m[i]);
27         extend_gcd(Mi,m[i],x,y);
28         ans=(ans+M+Mi*x*a[i])%M;
29     }
30     //if(ans<0)
31     //    ans+=M;
32     return ans;
33 }
34 inline int gg(){
35     freopen("HanXin.in","r",stdin);
36     freopen("HanXin.out","w",stdout);
37     scanf("%lld%d",&n,&m);
38     for(int i=1;i<=m;i++)
39         scanf("%lld%lld",&mod[i],&a[i]);
40     L ans(CRT(a,mod,m));
41     if(ans>n){
42         puts("-1");
43         return 0;
44     }
45     while(ans<n)
46         ans+=M;
47     ans-=M;
48     printf("%lld",n-ans);
49 }
50 int k(gg());
51 int main(){;}

需要注意的是,要求的是最小损失人数,稍微处理一下结果即可

[COGS 2160]丧心病狂的韩信大点兵

题目

  懒得粘了,上链接= =

  http://cogs.pro/cogs/problem/problem.php?pid=2160

  这道题显然不能用普通的CRT做,因为它们不互质

  此时我们就要采用两两合并的思想,假设要合并如下两个方程

    x=a1+m1x1

    x=a2+m2x2

  那么得到

    a1+m1x1=a2+m2x2 ? m1x1+m2x2=a2-a1

  再利用扩展欧几里得解出x1的最小整数解,再代入

   x=a1+m1x1

得到x后,合并为一个方程的结果为

y≡x(mod lcm(m1,m2))

这样一直合并下去,最终可以求得解

代码如下:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 typedef long long L;
 6 int m;
 7 L a[21],mod[21];
 8 inline L gcd(L a,L b){
 9     return a%b?gcd(b,a%b):b;
10 }
11 inline L ext_gcd(L a,L b,L &x,L &y){
12     if(b==0){
13         x=1;
14         y=0;
15         return a;
16     }
17     L gcd(ext_gcd(b,a%b,x,y));
18     L tmp(x);
19     x=y;
20     y=tmp-(a/b)*y;
21     return gcd;
22 }
23 inline L ny(L a,L b){
24     L x,y;
25     L gcd(ext_gcd(a,b,x,y));
26     if(gcd!=1)
27         return -1;
28     return (x%b+b)%b;
29 }
30 inline bool merge(L a1,L m1,L a2,L m2,L &a3,L &m3){
31     L d(gcd(m1,m2));
32     L c=a2-a1;
33     if(c%d)
34         return false;
35     c=(c%m2+m2)%m2;
36     m1/=d;
37     m2/=d;
38     c/=d;
39     c*=ny(m1,m2);
40     c%=m2;
41     c*=m1*d;
42     c+=a1;
43     m3=m1*m2*d;
44     a3=(c%m3+m3)%m3;
45     return true;
46 }
47 L CRT(L a[],L m[],int n){
48     L a1(a[1]),m1(m[1]);
49     for(int i=2;i<=n;i++){
50         L a2(a[i]),m2(m[i]),a3,m3;
51         if(!merge(a1,m1,a2,m2,a3,m3))
52             return -1;
53         a1=a3;
54         m1=m3;
55     }
56     return (a1%m1+m1)%m1;
57 }
58 inline int gg(){
59     freopen("weakhanxin.in","r",stdin);
60     freopen("weakhanxin.out","w",stdout);
61     scanf("%d",&m);
62     for(int i=1;i<=m;i++)
63         scanf("%lld%lld",&mod[i],&a[i]);
64     printf("%lld",CRT(a,mod,m));
65 }
66 int k(gg());
67 int main(){;}

ps:这份代码是目前COGS上rk1的代码,在各种0.002s中出现一个0.000s,让我这个鶸鷄感觉有些方= =

时间: 2024-08-13 19:25:29

[补档]各种奇怪的韩信问题的相关文章

[补档]两个奇怪的大水题

导引 这是两道由OSU(貌似是一个我没有听说过的游戏)引申出的大水题(淼到不行啊喂),壹佰万行代码哦. T1 OSU! 题目 osu 是一款群众喜闻乐见的休闲软件. 我们可以把osu的规则简化与改编成以下的样子: 一共有n次操作,每次操作只有成功与失败之分,成功对应1,失败对应0,n次操作对应为1个长度为n的01串.在这个串中连续的 X个1可以贡献X^3 的分数,这x个1不能被其他连续的1所包含(也就是极长的一串1,具体见样例解释) 现在给出n,以及每个操作的成功率,请你输出期望分数,输出四舍五

记录 [补档]

数学 概率论 计数问题 数论 线性代数 博弈论 比赛经验 不要通过数据大小猜测正解的时间复杂度. 把一个方法想到底. DP题假如实在不会的话, 果断跳过, 找思维量更小的数据结构题. 一些方法 二分 DP, 尤其多想矩阵乘法优化DP 网络流 FFT 日程表 Fri, Nov 10 明天就是NOIp了. 从上次记录到现在已经将近一个月了, 这个月, 真心没有进步多少, 完全不再状态. 希望不要AFO吧. 这可能是最后一篇记录了. Sun, Oct 22 AHOI 2009 中国象棋: 统计在棋盘上

[补档]Cube

Cube 题目 给你一个n×m的棋盘,有一个1×1×2的长方体竖直放在(1,1)上,你可以将其在棋盘上滚动,你的目标是让其竖直放在(n,m)上,问至少需要多少次操作.(放倒.竖直.翻滚) INPUT 一行,两个整数n,m (n<=m) OUTPUT 需要最少时间逃脱密室.若无解输出impossible. SAMPLE INPUT1 1 1 OUTPUT1 0 INPUT2 2 4 OUTPUT2 3 INPUT3 4 7 OUTPUT3 6 解题报告 看到"逃离密室"这四个字我是

Leave It Behind and Carry On ---- 高一下期末考反思 [补档]

背景 这个学期的前\(\frac{3}{4}\), 我都是在停课集训中度过的, 先是GDKOI, 再是北京集训, 最后是GDOI, 结果GDOI还没进day3就滚粗了. 学校的内容是考完GDOI后回学校自学的, 这段时间里我继续停课自学了3个星期, 然后回班上了3个星期的课, 就期末考了. 期末考不出所料地挂得一塌涂地. 当然, 有的人说, 一个半月学完整个学期(4个月)的课程, 也不必对自己期望太高等等. 我认为实则不然. YAY大佬即便在同样停课的情况下, 期末考还考了年级第\(28\),

[补档]暑假集训D3总结

考试 集训第一次考试,然而- - 总共四道题,两道打了DFS,一道暴力,一道~~输出样例~~乱搞,都是泪啊- - 目前只改了三道,回头改完那道题再上题解吧- - T2 [Poi2010]Monotonicity 2   https://hzoi-mafia.github.io/2017/07/27/20/ T3 [中山市选2011]杀人游戏   https://hzoi-mafia.github.io/2017/07/27/19/ T4 弱题  https://hzoi-mafia.github

[补档]2017-7-9至2017-7-15小集训总结

关于考试 说实话,没想到能考成这个样子,总共不到30个人,D1考试rk4,到D4rk二十几,真是interesting(annoying),明明有好多题都基本上是正解却还不如暴力分多啊喂= = 明明打上了矩阵,结果发现矩阵建成了一坨奇奇怪怪的东西,明明能现场推出来tarjan(不要问我为什么要现场推= =),却生生要用它打dfs,明明最暴力都能过的题(谁能告诉我为啥树剖T的题,一个一个爬就能过),明明树剖都打完了,线段树竟然不会打了... 这事情真的难办啊... 关于刷题 这几天的题也是很神奇的

[补档][国家集训队2011]单选错位

题目 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案. 试卷上共有n道单选题,第i道单选题有ai个选项,这ai个选项编号是1,2,3,-,ai,每个选项成为正确答案的概率都是相等的.lc采取的策略是每道题目随机写上1-ai的某个数作为答案选项,他用不了多少时间就能期望做对sigma(1/ai)道题目.gx则是认认真真地做完了这n道题目,可是等他做完的时候时间也所剩无几了,于是他匆忙地把答案抄到答题纸上,没想到抄错位了:第i道题目的答案抄到了答题纸上的第

[补档][中山市选2011]杀人游戏

题目 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人,谁是杀手,谁是平民.假如查证的对象是杀手,杀手将会把警察干掉. 现在警察掌握了每一个人认识谁. 每一个人都有可能是杀手,可看作他们是杀手的概率是相同的. 问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少? INPUT 第一行有两个整数 N,M. 接下来有 M 行,每行两个整数 x,y,表示 x 认识 y(

[补档计划] 类欧几里得算法

$$\begin{aligned} f(a, b, c, n) & = \sum_{i = 0}^n \lfloor \frac{ai + b}{c} \rfloor \\ & = \sum_{i = 0}^n \sum_{j = 0}^{m-1} [j < \lfloor \frac{ai + b}{c} \rfloor] \\ & = \sum_{i = 0}^n \sum_{j = 0}^{m-1} [j + 1 \le \lfloor \frac{ai + b}{c}