ICPC 2018 徐州赛区网络赛

ACM-ICPC 2018 徐州赛区网络赛

?去年博客记录过这场比赛经历:该死的水题

?一年过去了,不被水题卡了,但难题也没多做几道。水平微微有点长进。

?
?

D. Easy Math

题意:

? 给定 \(n\), \(m\) ,求 \(\sum _{i=1}^{m} \mu(in)\) 。其中 $ 1 \le n \le 1e12$ , $ 1 \le m \le 2e9$ ,\(\mu(n)\) 为莫比乌斯函数。
?

思路:

? 容易知道,\(i\) 与 \(n\) 不互质时, \(\mu(in)\) 恒为0。又由于互质时,\(\mu(in) = \mu(i) \mu(n)\) 。
? 设 \[F(n,m)=\sum_{i=1}^{m}\mu(i\cdot n)\]
? 则有\[F(n,m)=\mu(n)\cdot\sum_{i=1}^{m}\mu (i)\cdot[gcd(i,n)==1]\]
? 由\[\sum_{d|n}^{ } \mu(d)=[n==1]\]
\[F(n,m)=\mu(n)\cdot\sum_{i=1}^{m}\mu (i) \cdot \sum_{d|gcd(i,n)}^{ }\mu(d)\]
\[F(n,m)=\mu(n)\cdot\sum_{d|n}^{d\leqslant m}\mu(d)\cdot\sum_{i=1}^{\left \lfloor \frac{m}{d} \right \rfloor}\mu(i\cdot d)\]
\[F(n,m)=\mu(n)\cdot\sum_{d|n}^{d\leqslant m}\mu(d)\cdot F(d,\left \lfloor \frac{m}{d} \right \rfloor)\]
?推出递推式后,可以递归求解。
?当n=1时,有 \(muSum(n)=\sum_{i=1}^{m}\mu(i)\) ,这个和式利用莫比乌斯反演(杜教筛),结果为 \(muSum(n)=1-\sum_{i=2}^{n}muSum(\left \lfloor \frac{n}{i} \right \rfloor)\),详见我的博客
?

AC代码:

#include<iostream>
#include<cstdio>
#include<unordered_map>
using namespace std;
const int maxn = 2000000;
typedef long long ll;

ll prime[maxn+5];
int tot;
bool vis[maxn+5];
ll mu[maxn+5];
ll Smu[maxn+5];

void getP(int n) {
    vis[1] = 1;
    mu[1] = 1;
    prime[0] = 1;
    for(int i=2;i<=n;i++) {
        if(!vis[i]) {
            prime[++tot] = i;
            mu[i] = -1;
        }

        for(int j=1;j<=tot && i*prime[j]<=n;j++) {
            vis[i*prime[j]] = 1;
            if(i%prime[j])
                mu[i*prime[j]] = -mu[i];
            else {
                mu[i*prime[j]] = 0;
                break;
            }
        }
    }

    for(int i=1;i<=maxn;i++) {
        Smu[i] = Smu[i-1] + mu[i];
    }
}

unordered_map<int, ll> Sum;
ll muSum(ll n) {
    if(n<=maxn) return Smu[n];
    if(Sum.count(n)) return Sum[n];

    ll res = 0;
    for(ll l=2,r;l<=n;l=r+1) {
        r = n/(n/l);
        res += (r+1-l) * muSum(n/l);
    }
    return Sum[n] = 1-res;
}
ll getmu(ll n) {
    if(n<=maxn) return mu[n];
    ll k = 1;
    for(ll i=2;i*i<=n;i++) {
        if(n%i==0) {
            if(n%(i*i)==0)
                return 0;
            k *= -1;
            n /= i;
        }
    }
    if(n>1)
        k *= -1;
    return k;
}
ll f(ll m, ll n) {
    if(m==0) return 0;
    if(m==1) return getmu(n);
    if(n==1) return muSum(m);

    ll res = 0;
    for(ll d=1;d*d<=n && d<=m;d++) {
        if(n%d==0) {
            res += getmu(d)*f(m/d, d);
            if(n/d<=m) res += getmu(n/d)*f(m/(n/d), n/d);
        }
    }
    return getmu(n)*res;
}

ll m, n;
int main() {
    getP(maxn);
    cin>>m>>n;
    cout<<f(m, n)<<endl;

    return 0;
}

?

F. Features Track

题意:

?给出 \(n\) 个时刻(帧)猫的状态,每个状态用 \(<a, b>\) 表示。如果相同的状态在多个连续时刻出现,则构成了一种运动。求最长的这种运动。

?

思路:

?签到题,SLT map pair的使用。注意状态去重!!!
?

AC代码:


点击查看代码
#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;

typedef pair<int, int> pii;
map<pii, int> S;

int id;
const int maxn = 100100;
vector<int> arr[maxn];

int ID(pii a) {
    if(S.find(a)!=S.end()) return S[a];
    return S[a]=++id;
}

int main() {
    int t; cin>>t;
    while(t--) {
        int n, k, maxid = 0;
        scanf("%d", &n);
        for(int i=1;i<=n;i++) {
            scanf("%d", &k);
            while(k--) {
                int a, b;
                scanf("%d %d", &a, &b);
                int id = ID(make_pair(a, b));
                arr[id].push_back(i);
          //      cout<<id<<' '<<i<<endl;
                maxid = max(maxid, id);
            }
        }
        int ans = 0;
        for(int i=1;i<=maxid;i++) {
            if(arr[i].size()==0) continue;
            else if(arr[i].size()==1) {
                ans = max(ans, 1);
                continue;
            }
            sort(arr[i].begin(), arr[i].end());
            unique(arr[i].begin(), arr[i].end());  // 去重!!!

            int now = 1;
            for(int j=1;j<arr[i].size();j++) {
                if(arr[i][j]==arr[i][j-1]+1) {
                    ans = max(ans, ++now);
                } else {
                    now = 1;
                }

            }
        }
        printf("%d\n", ans);

        id = 0;
        S.clear();
        for(int i=1;i<=maxid;i++)
            arr[i].clear();
    }

    return 0;
}

?

H. Ryuji doesn‘t want to study

题意:

?有 \(n\) 本书,每本书分别有 \(a[i]\) 的知识点。看书从 \(l\) 到 \(r\) 能得到的知识点为 \(a[l]×L+a[l+1]×(L?1)+?+a[r?1]×2+a[r]\) ,其中 \(L = r - l + 1\) 。有 次询问,询问分为两种 1. 询问\([l, r]\) 区间的知识点。 2. 将第 \(b\) 本书知识点改为 \(c\) 。
?

思路:

??稍微推导一下公式,可以发现可以维护两段前缀和 \(sum1[n] = \sum_{1}^{n} a_i\) 与 \(sum2[n] = \sum_{1}^{n} ia_i\) ,那么\(ans[l, r] = (sum2[r]-sum2[l-1]) - (n-r)(sum2[r]-sum2[l-1])\) ,于是用树状数组很快就写出来了。
??注意add函数里应该为 \(x\le n\) ,开始写小于WA了一发。。。
??改成线段树,爆了 ll 又WA了一次

?

AC代码:

树状数组写法

#include<iostream>
#include<cstdio>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long ll;
const int maxn = 100100;

ll C1[maxn];
ll C2[maxn];
int n, q;
ll arr[maxn];

void add(ll C[], int x, ll val) {
    while(x<=n) {
        C[x] += val;
        x += lowbit(x);
    }
}

ll sum(ll C[], int x) {
    ll res = 0;
    while(x) {
        res += C[x];
        x -= lowbit(x);
    }
    return res;
}

int main() {
    cin>>n>>q;
    for(int i=1;i<=n;i++) {
        ll val;
        scanf("%lld", &val);
        arr[i] = val;
        add(C1, i, val);
        add(C2, i, val*(n+1-i));
    }

    while(q--) {
        int op;
        ll l, r;
        scanf("%d %lld %lld", &op, &l, &r);
        if(op==1) {
            ll Sum1 = sum(C2, r) - sum(C2, l-1);
            ll Sum2 = sum(C1, r) - sum(C1, l-1);
            printf("%lld\n", Sum1 - Sum2*(n-r));
        } else {
            add(C1, l, r-arr[l]);
            add(C2, l, (r-arr[l])*(n+1-l));
            arr[l] = r;
        }
    }
    return 0;
}

?

线段树写法


点击查看代码
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define MID (l+r)>>1
const int maxn = 100010;
typedef long long ll;

ll t1[maxn<<2];
ll t2[maxn<<2];
ll arr[maxn];
int n;

void build(ll t[], bool f, int rt, int l, int r) {
    if(l==r) {
        if(f)
            t[rt] = arr[l];
        else
            t[rt] = arr[l]*(n+1-l);
        return;
    }
    int mid = MID;
    build(t, f, lson);
    build(t, f, rson);
    t[rt] = t[rt<<1] + t[rt<<1|1];
}

void update(ll t[], int pos, ll val, int rt, int l, int r) {
    if(l==r) {
        t[rt] += val;
        return;
    }

    int mid = MID;
    if(pos<=mid)
        update(t, pos, val, lson);
    else
        update(t, pos, val, rson);

    t[rt] = t[rt<<1] + t[rt<<1|1];
}

ll query(ll t[], int L, int R, int rt, int l, int r) {
    if(L<=l && R>=r) {
        return t[rt];
    }

    ll ans = 0;
    int mid = MID;
    if(L<=mid)
        ans += query(t, L, R, lson);
    if(mid<R)
        ans += query(t, L, R, rson);
    return ans;
}

int main() {
    int q;
    scanf("%d %d", &n, &q);
    for(int i=1;i<=n;i++) {
        scanf("%lld", &arr[i]);
    }

    build(t1, 1, 1, 1, n);
    build(t2, 0, 1, 1, n);

    while(q--) {
        int op;
        ll l, r;
        scanf("%d %d %d", &op, &l, &r);
        if(op==1) {
            ll sum1 = query(t1, l, r, 1, 1, n);
            ll sum2 = query(t2, l, r, 1, 1, n);
            sum2 -= sum1 * (n-r);
            printf("%lld\n", sum2);
        } else {
            update(t1, l, r-arr[l], 1, 1, n);
            update(t2, l, (r-arr[l])*(n+1-l), 1, 1, n);

            arr[l] = r;
        }
    }
    return 0;
}

?

I. Characters with Hash

题意:

? 水题,签到。
?

AC代码:


点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;

char str[1000100];
int main() {
    int t; cin>>t;
    while(t--) {
        int n; char c;
        cin>>n>>c;
        scanf("%s", str);
        int s = 0;
        while(s<n && str[s]==c) ++s;
        if(s==n) {
            printf("1\n");
            continue;
        }
        if(abs(str[s]-c)>=10) {
            printf("%d\n", (n-s)*2);
        } else {
            printf("%d\n", (n-s)*2-1);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/izcat/p/11441093.html

时间: 2024-10-05 23:58:09

ICPC 2018 徐州赛区网络赛的相关文章

ACM-ICPC 2018 徐州赛区(网络赛)

A. Hard to prepare After Incident, a feast is usually held in Hakurei Shrine. This time Reimu asked Kokoro to deliver a Nogaku show during the feast. To enjoy the show, every audience has to wear a Nogaku mask, and seat around as a circle. There are

ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn&#39;t want to study (线段树)

Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]. Unfortunately, the longer he learns, the fewer he gets. That means, if he reads books from ll to rr, he will get a

ACM-ICPC 2018 徐州赛区网络预赛 D. EasyMath

ACM-ICPC 2018 徐州赛区网络预赛 D. EasyMath 做法: \[f(m,n) = \sum _{i=1}^{m} \mu(in) = \sum_{i=1}^{m}[gcd(i,n)=1]\mu(i)\mu(n) = \mu(n)\sum_{d|n}\mu(d)f(\frac{m}{d},d)\] 边界: n=1,杜教筛求\(\sum_{i=1}^{m}\mu(i)\),m = 1, 返回\(\mu(n)\),预处理尽可能把空间卡满. 2个小时的时候就推出来了这个式子,不会算复杂

ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn&#39;t want to study

262144K Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i]. Unfortunately, the longer he learns, the fewer he gets. That means, if he reads books from ll to rr, he wi

ACM-ICPC 2018 徐州赛区网络预赛 B. BE, GE or NE

In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named "Sena" are playing a video game. The game system of this video game is quite unique: in the process of playing this game, you need to constantly fac

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)

ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N \times MN×M little squares. That is to say, the h

ACM-ICPC 2018 徐州赛区网络预赛

Rank Solved A B C D E F G H I J K 157/1526 7/11 O O ? ? . O O O O O ? O: 当场通过 ?: 赛后通过 .: 尚未通过 A Hard to prepare solved by chelly chelly's solution B BE, GE or NE solved by ch ch's solution C Cacti Lottery upsolved by chelly chelly's solution 考虑枚举*代表的

ACM-ICPC 2018 徐州赛区网络预赛 A. Hard to prepare

传送门:https://nanti.jisuanke.com/t/31453 本题是一个组合数学(DP,滑稽)题. 一个环上有N个位置,标号为1~N.设第i(1≤i≤N)个位置上的数为x[i],限制条件为:0≤x[i]<2k.另有限制条件:当位置i和位置j相邻时,x[i]⊕x[j]≠2k-1.求满足限制条件的环的状态数. 可以考虑将环切割成链,以分析问题.设: ①a[n]:长度为n,且首尾相同的满足上述条件的链的状态数: ②b[n]:长度为n,且首尾相反的满足上述条件的链的状态数: ③c[n]:

【ACM-ICPC 2018 徐州赛区网络预赛】E. End Fantasy VIX 血辣 (矩阵运算的推广)

Morgana is playing a game called End Fantasy VIX. In this game, characters have nn skills, every skill has its damage. And using skill has special condition. Briefly speaking, if this time you use skill "x", then next time you can use skill &quo