A 签到题

链接:http://222.204.56.169/contest/20/problem/A
题意
找规律签到
题解
按照给的代码多组输入一下,找到规律,写出来即可
代码

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    if(n&1)printf("1");else printf("-1");
    return 0;
}

B 阶乘

链接:http://222.204.56.169/contest/19/problem/B
题意
找一个数后面有几个0
题解
其实就是因子中有多少个5,因为5存在一个5前面就有一个2,就是找因子中存在5的个数,例如:n=31中,有因子-> 5 10 15 20 25 30 (31/5=6就是代表这几个数的个数) 然后每五个这样连续的数就会出现5*5这样的数,所以(得到的6/5=1)再加进去直到n=0为止

代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n,num;
cin>>n;
 num=0;
while(n!=0)
{
num=num+n/5;
n=n/5;
}
cout<<num<<endl;
return 0;

}

C 合并滑稽

链接:http://222.204.56.169/contest/19/problem/C
题意
把一串数并在一起,每一次需要消耗对应的数相加的体力。使得体力消耗最小。
题解
每一次的合并,之前的数都要算一遍,也就是说小的数线合并所消耗的体力会最小,只要每次都用一个sort排序就好了。
代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100005];
int main()
{
    int n;
    scanf("%d",&n);
    memset(a,0,sizeof(a));
    for(int i=0;i<n;i++)
    {scanf("%d",&a[i]);}
    int ans=0;
    for(int i=0;i<n-1;i++)
    {
        sort(a,a+n);
        a[i+1]+=a[i];
        ans+=a[i+1];
        a[i]=0;
    }
    printf("%d",ans);
    return 0;
}

D ff爱组合数

链接:http://222.204.56.169/contest/19/problem/D
题意
就是求C_n^m的组合数%p
题解
可以利用递推(具体的实践在算法笔记P186)
代码

#include<iostream>
#include<cstdio>
using namespace std;
const int p=1e9+9;
int res[20009][2009]={0};
int n,m;
void calC(int x)
{
    for(int i=0;i<x;i++)
    {
        res[i][0]=res[i][i]=1;
    }
    for(int i=2;i<=x;i++)
    {
        for(int j=0;j<=i/2;j++)
        {
            res[i][j]=(res[i-1][j]+res[i-1][j-1])%p;
            res[i][i-j]=res[i][j];
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    int n,m;
    calC(2000);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        printf("%d\n",res[n][m]);
    }
    return 0;
}

E 猜猜在哪里

链接:http://222.204.56.169/contest/19/problem/E
题意
题解
注意:我不会呀~~呜呜呜呜
代码

#include <bits/stdc++.h>
using namespace std;
const int N = 200000 + 10;
typedef long long LL;
const LL MOD = 998244353;
LL mpow(LL a, LL x) {
    if (x == 0) return 1;
    LL t = mpow(a, x>>1);
    if (x % 2 == 0) return t * t % MOD;
    return t * t % MOD * a % MOD;
}
struct Nod {
    LL k, b, s;
    Nod operator + (const Nod & o) const {
        Nod ans;
        ans.k = 1; ans.b = 0;
        ans.s = (s + o.s) % MOD;
        return ans;
    }
} nod[N << 2];
void build(int l,int r,int rt){
    if(l==r){
        nod[rt].k=1,nod[rt].b=0;nod[rt].s=0; return;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    nod[rt] = nod[rt<<1] + nod[rt<<1|1];
}
void upd(int rt, LL k, LL b) {
    nod[rt].k = nod[rt].k * k % MOD;
    nod[rt].b = (nod[rt].b * k + b) % MOD;
    nod[rt].s = (nod[rt].s * k + b) % MOD;
}
void pushdown(int rt) {
    upd(rt<<1, nod[rt].k, nod[rt].b);
    upd(rt<<1|1, nod[rt].k, nod[rt].b);
    nod[rt].k = 1, nod[rt].b = 0;
}
void update(int l,int r,int rt,int L,int R,LL k,LL b){
    if (L<=l&&r<=R) {
        upd(rt, k, b); return;
    }
    pushdown(rt); int mid=(l+r)>>1;
    if(L<=mid) update(l,mid,rt<<1,L,R,k,b);
    if(R >mid) update(mid+1,r,rt<<1|1,L,R,k,b);
    nod[rt]=nod[rt<<1]+nod[rt<<1|1];
}
int query(int l,int r,int rt,int pos){
    if(l==r){
        return nod[rt].s;
    }
    pushdown(rt); int mid=(l+r)>>1;
    if(pos<=mid) return query(l,mid,rt<<1,pos);
    return query(mid+1,r,rt<<1|1,pos);
}
void modify(int l,int r,int rt,int pos,int x){
    if(l==r){
        nod[rt].s=x; return;
    }
    pushdown(rt); int mid=(l+r)>>1;
    if(pos<=mid) modify(l,mid,rt<<1,pos,x);
    else modify(mid+1,r,rt<<1|1,pos,x);
    nod[rt] = nod[rt<<1] + nod[rt<<1|1];
}
int t;LL n, m, k;
bool flag[N]; int item1[N], item2[N];
LL inv(LL x){
    return mpow(x%MOD, MOD-2);
}
const bool CHK = 0;
LL A[N];
void ran_swap() {
    // tot = 1, myval = x
    // N: (n-2)/n * x
    // Y: 2/(n(n-1)) * (1 - x)
    // [(n-2)/n - 2/(n(n-1))] * x + 2/(n(n-1))
    LL k = (n-2)*inv(n) - 2*inv(n*(n-1)); k = (k % MOD + MOD) % MOD;
    LL b = 2*inv(n*(n-1)); b = (b % MOD + MOD) % MOD;
    update(1,n,1,1,n,k,b);
    if (CHK) {
        for (int i = 1; i <= n; i ++) {
            LL ans = (n-2) * inv(n) % MOD * A[i] % MOD;
            ans += 2 * inv(n) % MOD * ( (1 - A[i] + MOD) % MOD * inv(n-1) % MOD ) % MOD;
            ans %= MOD;
            A[i] = ans;
        }

    }
}
void _swap(int x, int y) {
    int v1 = query(1,n,1,x);
    int v2 = query(1,n,1,y);
    modify(1,n,1,x,v2);
    modify(1,n,1,y,v1);
    if (CHK) swap(A[x], A[y]);
}
void chk() {
    for (int i = 1; i <= n; i ++) {
        printf("# %lld %d\n", A[i], query(1,n,1,i));
        assert(A[i] == query(1,n,1,i));
    }
}
int main() {
    scanf("%d", &t);
    while (t --) {
        scanf("%lld%lld%lld", &n, &m, &k);
        build(1, n, 1); modify(1, n, 1, 1, 1);
        for (int i = 1; i <= n; i ++) A[i] = 0; A[1] = 1;
        for (int i = 1; i <= m; i ++) {
            flag[i] = 0;
        }
        for (int i = 1; i <= k; i ++) {
            int op,x,y; scanf("%d%d%d",&op,&x,&y);
            flag[op] = 1; item1[op] = x, item2[op] = y;
        }
        for (int i = 1; i <= m; i ++) {
            if (flag[i]) {
                _swap(item1[i], item2[i]);
            } else {
                ran_swap();
            }
        }
        if (CHK) {
            chk();
        }
        for (int i = 1; i <= n; i ++) {
            printf("%d%c", query(1,n,1,i),i==n?'\n':' ');
        }
        LL s = 0;
        for (int i = 1; i <= n; i ++) {
            s += query(1,n,1,i);
            s %= MOD;
        }
        assert(s == 1);
        //printf("sum = %lld\n", s);
    }
}

F 约数的个数

链接:http://222.204.56.169/contest/19/problem/F
题意
f(n)为n约数的个数,求F(n)=1f(1)+2f(2)+、、、+n*f(n)

题解:神奇的筛法

for(int i=1;i<=n;i++)
    for(int j=i;j<=n;j+=i)
        F[j]++;

注意:自行理解,其实表示的就是i为约数的时候,每一个n以内的数都会进行一个计算作为i的倍数对应数字j的约数个数+1,这样其实就是算出来了n以内的所有不同数字对应的约数个数。然后叠加一下就可以啦~
代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll f[1000006];
ll F[1000006];
void iserv(ll n)
{
    for(ll i=1;i<=n;i++)
        for(ll j=i;j<=n;j+=i)
            f[j]++;
}
int main()
{
    ll x;
    scanf("%lld",&x);
    memset(f,0,sizeof(f));
    iserv(x);
    F[1]=1*f[1];
    for(ll i=2;i<=x;i++)
    {
        F[i]=F[i-1]+i*f[i];
    }
    printf("%lld",F[x]);
    return 0;
}