20201007 刷题记录(3题)

题目列表

  • 余数研究
  • 滑水
  • n阶方程

余数研究

CF922C

题目描述

输入 n n n k k k,判断 n  mod  1 ∼ k n\text{ mod } 1\sim k n mod 1k每个数的余数是不是都不相同

输入

输入数据包含多组,每行两个数字 n n n k k k,空格隔开。 以0 0结束

输出

对于每行的有效数据,如果所有余数均不相同,输出yes,否则输出No.

样例输入

4 4
5 3
0 0

样例输出

No
Yes

说明/提示

n , k ≤ 1 0 18 n,k≤10^{18} n,k1018

【样例解释】

对于4 4
由于4 mod 1和4 mod 2都是0,所以是No
对于5 3
由于5 mod 1=0
5 mod 2 = 1
5 mod 3 = 2
所以余数各不相同,输出Yes

分析

如果取余的都不相同,则寻找规律得到: n  mod  i = i − 1 ( i ≠ 0 ) n\text{ mod }i = i-1(i\neq 0) n mod i=i1(i=0)
然后,直接从 1 ∼ k 1 \sim k 1k循环一次判断即可。记得开 long long \text{long long} long long.

代码

#include<bits/stdc++.h>
using namespace std;
int main() {
    long long n,k;
    while(cin>>n>>k) {
        if(n == k && n == 0 && k == 0)return 0;
        int flag=1;
        for(long long i=1; i<=k; i++) {
            if(n%i!=i-1) {
                flag=0;
                break;
            }
        }
        if(flag)printf("Yes\n");
        else printf("No\n");
    }return 0;
}

时间复杂度

O ( T k ) O(T k) O(Tk)

1658: [Usaco2006 Mar]Water Slides 滑水

USACO 2006 Mar.

Description

It’s a hot summer day, and Farmer John is letting Betsy go to the water park where she intends to ride every single slide. The water park has N ( 1 ≤ N ≤ 10 , 000 ) N (1 \leq N \leq 10,000) N(1N10,000) platforms (numbered 1... N 1...N 1...N) from which to enter the M ( 1 ≤ M ≤ 10 , 000 ) M (1 \leq M \leq 10,000) M(1M10,000) water slides. Each water slide starts at the top of some platform and ends at the bottom of some platform (possibly the same one). Some platforms might have more than one slide; some might not have any. The park is very thin, so the platforms lie along a straight line, each platform at a position X i ( 0 ≤ X i ≤ 100 , 000 ) X_i (0 \leq X_i \leq 100,000) Xi(0Xi100,000) meters from one end of the park. One walks from one platform to the next via a sidewalk parallel to the line of platforms.The platforms of the water park are weakly connected; that is, the park cannot be divided into two sets of platforms with no slides running between the two sets. Both the entrance and exit to the park are at platform 1 1 1, so Betsy will start and end there. In order to spend more time on the slides, Betsy wants to walk as little as possible. Find the minimum distance Betsy must travel along the ground in order to try every slide in the park exactly once without repeating.

Input

  • Line 1 1 1: Two integers, N N N and M M M.
  • Lines 2... N + 1 2...N+1 2...N+1: Line i + 1 i+1 i+1 contains one integer, X i X_i Xi, the position of platform i i i.
  • Lines N + 2... M + N + 1 N+2...M+N+1 N+2...M+N+1: Line i + N + 1 i+N+1 i+N+1 contains two integers, S i S_i Si and D i D_i Di, respectively the start and end platforms of a slide.

Output

  • Line 1 1 1: One integer, the minimum number of meters Betsy must walk.

Sample Input

5 7
5
3
1
7
10
1 2
1 2
2 3
3 1
4 5
1 5
4 1

Sample Output

8

分析

定义 a x a_x ax x x x点的入度出度之差(其中 x x x表示坐标)
于是分类讨论:

  • ① ① a x > 0 a_x > 0 ax>0则步行通过 x x x点一定需要 a x a_x ax次.
  • ② ② a x < 0 a_x < 0 ax<0则一定要从 x x x步行出发 a x a_x ax次.
    由上,推出
    ∑ a i = 0. \sum a_i = 0. ai=0.
    最优解一定是对于每个 a x > 0 a_x >0 ax>0 x x x, 找目前最近的 a y < 0 a_{y} < 0 ay<0 x x x,
    y y y走到 x x x, 然后 a x − 1 , a y + 1 a_x-1,a_y+1 ax1,ay+1, 然后再统计一下即可。
    时间复杂度
    O ( n ) O(n) O(n)

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,a[10004],cd[100004],x,y,ans;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=0;i<m;i++){
        scanf("%d%d",&x,&y);
        cd[a[x]]++;
        cd[a[y]]--;
    }
    ans=cd[0]<0?-1*cd[0]:cd[0];
    for(int i=1;i<=100000;i++){
        cd[i]+=cd[i-1];
        ans+=cd[i]<0?-1*cd[i]:cd[i];
    }
    printf("%d",ans);
    return 0;
}

n n n阶方程

noip2014

题目描述

已知多项式方程:
a 0 + a 1 x + a 2 x 2 + ⋯ + a n x n = 0 a_0+a_1x+a_2x^2+⋯+a_nx^n=0 a0+a1x+a2x2++anxn=0
求这个方程在 [ 1 , m ] [1,m] [1,m] 内的整数解( n n n m m m 均为正整数)。

输入

输入共 n + 2 n + 2 n+2 行。
第一行包含 2 2 2 个整数 n , m n, m n,m ,每两个整数之间用一个空格隔开。
接下来的 n + 1 n+1 n+1 行每行包含一个整数,依次为 a 0 , a 1 , . . . , a n a_0,a_1,...,a_n a0,a1,...,an

输出

第一行输出方程在 [ 1 , m ] [1,m] [1,m] 内的整数解的个数。
接下来每行一个整数,按照从小到大的顺序依次输出方程在 [ 1 , m ] [1,m] [1,m] 内的一个整数解。

样例输入

2 10 
1
-2
1

样例输出

1
1

提示

输入 #2
2 10
2
-3
1
输出 #2
2
1
2
输入 #3
2 10
1
3
2
输出 #3
0

数据范围

0 ≤ n ≤ , ∣ a i ∣ ≤ 1 0 10000 , a n ≠ 0 , m < 1 0 6 . 0 \leq n \leq, |a_i| \leq 10^{10000}, a_n \neq 0, m < 10^6. 0n,ai1010000,an=0,m<106.

分析

对于这道题显然不能暴力枚举,
但可以使用秦九韶算法。
a 0 + a 1 x + a 2 x 2 + a 3 x 3 + a 4 x 4 + . . . . . . + a n x n = 0 a_0+a_1x+a_2x^2+a_3x^3+a_4x^4+......+a_nx^n = 0 a0+a1x+a2x2+a3x3+a4x4+......+anxn=0
根据秦九韶算法转化成
( ( ( a n x + a n − 1 ) x + a n − 2 ) x . . . . . . + a 1 ) x + a 0 = 0 (((a_nx+a_{n-1})x+a_{n-2})x......+a_1)x+a_0 = 0 (((anx+an1)x+an2)x......+a1)x+a0=0
然后再枚举 i i i,每次计算对一个不会与式子整除的数字取模(代码中使用的是 19260817 19260817 19260817)使用高精度计算出解存在 a n s ans ans数组中, 其余记得开 long long \text{long long} long long然后就可以过了.

代码

#include <bits/stdc++.h>
using namespace std;
const long long mod=19260817;
char s[10005];
long long n,m,a[105],b[105],ans[1000005],cnt=0;
int main() {
    scanf("%lld%lld",&n,&m);
    for(long long i=0; i<=n; ++i) {
        scanf("%s",s);long long len=strlen(s);int flag=0;
        for(long long j=0; j<len; ++j) {
            if(s[j]=='-') {flag=1;continue;}
            a[i]=(a[i]*10+s[j]-'0')%mod;
        }if(flag==1)a[i]=-a[i],b[i]=-b[i];
    }
    for(long long i=1; i<=m; ++i) {
        long long tot=a[n];for(long long j=n-1; j>=0; --j)tot=(tot*i%mod+a[j])%mod;
        tot=(tot%mod+mod)%mod;if(tot!=0)continue;ans[++cnt]=i;
    }printf("%lld\n",cnt);
    for(long long i=1; i<=cnt; ++i)printf("%lld\n",ans[i]);
    return 0;
}

其中

for(long long i=0; i<=n; ++i) {
        scanf("%s",s);long long len=strlen(s);int flag=0;
        for(long long j=0; j<len; ++j) {
            if(s[j]=='-') {flag=1;continue;}
            a[i]=(a[i]*10+s[j]-'0')%mod;
        }if(flag==1)a[i]=-a[i],b[i]=-b[i];
    }

为类似高精度的读入。

时间复杂度

O ( n m ) O(nm) O(nm)

Thinks

by vibrant72 on Oct. 7th 2020, Wednesday.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值