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)=[n1]$$

\[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代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<unordered_map>
  4. using namespace std;
  5. const int maxn = 2000000;
  6. typedef long long ll;
  7. ll prime[maxn+5];
  8. int tot;
  9. bool vis[maxn+5];
  10. ll mu[maxn+5];
  11. ll Smu[maxn+5];
  12. void getP(int n) {
  13. vis[1] = 1;
  14. mu[1] = 1;
  15. prime[0] = 1;
  16. for(int i=2;i<=n;i++) {
  17. if(!vis[i]) {
  18. prime[++tot] = i;
  19. mu[i] = -1;
  20. }
  21. for(int j=1;j<=tot && i*prime[j]<=n;j++) {
  22. vis[i*prime[j]] = 1;
  23. if(i%prime[j])
  24. mu[i*prime[j]] = -mu[i];
  25. else {
  26. mu[i*prime[j]] = 0;
  27. break;
  28. }
  29. }
  30. }
  31. for(int i=1;i<=maxn;i++) {
  32. Smu[i] = Smu[i-1] + mu[i];
  33. }
  34. }
  35. unordered_map<int, ll> Sum;
  36. ll muSum(ll n) {
  37. if(n<=maxn) return Smu[n];
  38. if(Sum.count(n)) return Sum[n];
  39. ll res = 0;
  40. for(ll l=2,r;l<=n;l=r+1) {
  41. r = n/(n/l);
  42. res += (r+1-l) * muSum(n/l);
  43. }
  44. return Sum[n] = 1-res;
  45. }
  46. ll getmu(ll n) {
  47. if(n<=maxn) return mu[n];
  48. ll k = 1;
  49. for(ll i=2;i*i<=n;i++) {
  50. if(n%i==0) {
  51. if(n%(i*i)==0)
  52. return 0;
  53. k *= -1;
  54. n /= i;
  55. }
  56. }
  57. if(n>1)
  58. k *= -1;
  59. return k;
  60. }
  61. ll f(ll m, ll n) {
  62. if(m==0) return 0;
  63. if(m==1) return getmu(n);
  64. if(n==1) return muSum(m);
  65. ll res = 0;
  66. for(ll d=1;d*d<=n && d<=m;d++) {
  67. if(n%d==0) {
  68. res += getmu(d)*f(m/d, d);
  69. if(n/d<=m) res += getmu(n/d)*f(m/(n/d), n/d);
  70. }
  71. }
  72. return getmu(n)*res;
  73. }
  74. ll m, n;
  75. int main() {
  76. getP(maxn);
  77. cin>>m>>n;
  78. cout<<f(m, n)<<endl;
  79. return 0;
  80. }

 

F. Features Track

题意:

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

 

思路:

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

 

AC代码:

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<map>
  4. #include<vector>
  5. #include<algorithm>
  6. using namespace std;
  7. typedef pair<int, int> pii;
  8. map<pii, int> S;
  9. int id;
  10. const int maxn = 100100;
  11. vector<int> arr[maxn];
  12. int ID(pii a) {
  13. if(S.find(a)!=S.end()) return S[a];
  14. return S[a]=++id;
  15. }
  16. int main() {
  17. int t; cin>>t;
  18. while(t--) {
  19. int n, k, maxid = 0;
  20. scanf("%d", &n);
  21. for(int i=1;i<=n;i++) {
  22. scanf("%d", &k);
  23. while(k--) {
  24. int a, b;
  25. scanf("%d %d", &a, &b);
  26. int id = ID(make_pair(a, b));
  27. arr[id].push_back(i);
  28. // cout<<id<<' '<<i<<endl;
  29. maxid = max(maxid, id);
  30. }
  31. }
  32. int ans = 0;
  33. for(int i=1;i<=maxid;i++) {
  34. if(arr[i].size()==0) continue;
  35. else if(arr[i].size()==1) {
  36. ans = max(ans, 1);
  37. continue;
  38. }
  39. sort(arr[i].begin(), arr[i].end());
  40. unique(arr[i].begin(), arr[i].end()); // 去重!!!
  41. int now = 1;
  42. for(int j=1;j<arr[i].size();j++) {
  43. if(arr[i][j]==arr[i][j-1]+1) {
  44. ans = max(ans, ++now);
  45. } else {
  46. now = 1;
  47. }
  48. }
  49. }
  50. printf("%d\n", ans);
  51. id = 0;
  52. S.clear();
  53. for(int i=1;i<=maxid;i++)
  54. arr[i].clear();
  55. }
  56. return 0;
  57. }

 

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代码:

树状数组写法

  1. #include<iostream>
  2. #include<cstdio>
  3. #define lowbit(x) ((x)&(-x))
  4. using namespace std;
  5. typedef long long ll;
  6. const int maxn = 100100;
  7. ll C1[maxn];
  8. ll C2[maxn];
  9. int n, q;
  10. ll arr[maxn];
  11. void add(ll C[], int x, ll val) {
  12. while(x<=n) {
  13. C[x] += val;
  14. x += lowbit(x);
  15. }
  16. }
  17. ll sum(ll C[], int x) {
  18. ll res = 0;
  19. while(x) {
  20. res += C[x];
  21. x -= lowbit(x);
  22. }
  23. return res;
  24. }
  25. int main() {
  26. cin>>n>>q;
  27. for(int i=1;i<=n;i++) {
  28. ll val;
  29. scanf("%lld", &val);
  30. arr[i] = val;
  31. add(C1, i, val);
  32. add(C2, i, val*(n+1-i));
  33. }
  34. while(q--) {
  35. int op;
  36. ll l, r;
  37. scanf("%d %lld %lld", &op, &l, &r);
  38. if(op==1) {
  39. ll Sum1 = sum(C2, r) - sum(C2, l-1);
  40. ll Sum2 = sum(C1, r) - sum(C1, l-1);
  41. printf("%lld\n", Sum1 - Sum2*(n-r));
  42. } else {
  43. add(C1, l, r-arr[l]);
  44. add(C2, l, (r-arr[l])*(n+1-l));
  45. arr[l] = r;
  46. }
  47. }
  48. return 0;
  49. }

 

线段树写法

点击查看代码
  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstring>
  4. using namespace std;
  5. #define lson rt<<1, l, mid
  6. #define rson rt<<1|1, mid+1, r
  7. #define MID (l+r)>>1
  8. const int maxn = 100010;
  9. typedef long long ll;
  10. ll t1[maxn<<2];
  11. ll t2[maxn<<2];
  12. ll arr[maxn];
  13. int n;
  14. void build(ll t[], bool f, int rt, int l, int r) {
  15. if(l==r) {
  16. if(f)
  17. t[rt] = arr[l];
  18. else
  19. t[rt] = arr[l]*(n+1-l);
  20. return;
  21. }
  22. int mid = MID;
  23. build(t, f, lson);
  24. build(t, f, rson);
  25. t[rt] = t[rt<<1] + t[rt<<1|1];
  26. }
  27. void update(ll t[], int pos, ll val, int rt, int l, int r) {
  28. if(l==r) {
  29. t[rt] += val;
  30. return;
  31. }
  32. int mid = MID;
  33. if(pos<=mid)
  34. update(t, pos, val, lson);
  35. else
  36. update(t, pos, val, rson);
  37. t[rt] = t[rt<<1] + t[rt<<1|1];
  38. }
  39. ll query(ll t[], int L, int R, int rt, int l, int r) {
  40. if(L<=l && R>=r) {
  41. return t[rt];
  42. }
  43. ll ans = 0;
  44. int mid = MID;
  45. if(L<=mid)
  46. ans += query(t, L, R, lson);
  47. if(mid<R)
  48. ans += query(t, L, R, rson);
  49. return ans;
  50. }
  51. int main() {
  52. int q;
  53. scanf("%d %d", &n, &q);
  54. for(int i=1;i<=n;i++) {
  55. scanf("%lld", &arr[i]);
  56. }
  57. build(t1, 1, 1, 1, n);
  58. build(t2, 0, 1, 1, n);
  59. while(q--) {
  60. int op;
  61. ll l, r;
  62. scanf("%d %d %d", &op, &l, &r);
  63. if(op==1) {
  64. ll sum1 = query(t1, l, r, 1, 1, n);
  65. ll sum2 = query(t2, l, r, 1, 1, n);
  66. sum2 -= sum1 * (n-r);
  67. printf("%lld\n", sum2);
  68. } else {
  69. update(t1, l, r-arr[l], 1, 1, n);
  70. update(t2, l, (r-arr[l])*(n+1-l), 1, 1, n);
  71. arr[l] = r;
  72. }
  73. }
  74. return 0;
  75. }

 

I. Characters with Hash

题意:

  水题,签到。

 

AC代码:

点击查看代码
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. using namespace std;
  6. char str[1000100];
  7. int main() {
  8. int t; cin>>t;
  9. while(t--) {
  10. int n; char c;
  11. cin>>n>>c;
  12. scanf("%s", str);
  13. int s = 0;
  14. while(s<n && str[s]==c) ++s;
  15. if(s==n) {
  16. printf("1\n");
  17. continue;
  18. }
  19. if(abs(str[s]-c)>=10) {
  20. printf("%d\n", (n-s)*2);
  21. } else {
  22. printf("%d\n", (n-s)*2-1);
  23. }
  24. }
  25. return 0;
  26. }

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

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

    目录 A. Hard to prepare B.BE, GE or NE F.Features Track G.Trace H.Ryuji doesn't want to study I.Charac ...

  2. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  3. 计蒜客 1460.Ryuji doesn't want to study-树状数组 or 线段树 (ACM-ICPC 2018 徐州赛区网络预赛 H)

    H.Ryuji doesn't want to study 27.34% 1000ms 262144K   Ryuji is not a good student, and he doesn't wa ...

  4. ACM-ICPC 2018 徐州赛区网络预赛 B(dp || 博弈(未完成)

    传送门 题面: In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl n ...

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

    In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named &qu ...

  6. ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn'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 ...

  7. ACM-ICPC 2018 徐州赛区网络预赛 F. Features Track

    262144K   Morgana is learning computer vision, and he likes cats, too. One day he wants to find the ...

  8. ACM-ICPC 2018 徐州赛区网络预赛 I. Characters with Hash

    Mur loves hash algorithm, and he sometimes encrypt another one's name, and call him with that encryp ...

  9. ACM-ICPC 2018 徐州赛区网络预赛 D 杜教筛 前缀和

    链接 https://nanti.jisuanke.com/t/31456 参考题解  https://blog.csdn.net/ftx456789/article/details/82590044 ...

随机推荐

  1. LOJ #6538. 烷基计数 加强版 加强版(生成函数,burnside引理,多项式牛顿迭代)

    传送门. 不妨设\(A(x)\)表示答案. 对于一个点,考虑它的三个子节点,直接卷起来是\(A(x)^3\),但是这样肯定会计重,因为我们要的是无序的子节点. 那么用burnside引理,枚举一个排列 ...

  2. SCOI 2014 new :未来展望

    后期计划(可能延续到noip) 后期计划这种东西..唉...经历了三周的停课生涯,我似乎已经找到了一种状态,就是我一直期盼的状态,然后为了不落泪退役,具体是这样的: 由于现在的学习任务不太紧张了,所以 ...

  3. JavaWeb学习篇之----Servlet

    今天来继续学习JavaWeb的相关知识,之前都是都介绍一些基本知识,从今天开始我们来说一下如何在服务器编写程序,这里就需要来介绍一下Servlet的相关知识了.Servlet就是一个能够运行在服务器端 ...

  4. 线段树优化dp——牛客多校第一场I(好题)

    和两天做了两道数据结构优化dp的题,套路还是差不多的 题解链接! https://www.cnblogs.com/kls123/p/11221471.html 一些补充 其实这道题的dp[i]维护的不 ...

  5. android 插件化框架VitualAPK

    推荐阅读: 滴滴Booster移动App质量优化框架-学习之旅 一 Android 模块Api化演练 不一样视角的Glide剖析(一) LeakCanary 与 鹅场Matrix ResourceCa ...

  6. JS中 reduce() 的用法

    过去有很长一段时间,我一直很难理解 reduce() 这个方法的具体用法,平时也很少用到它.事实上,如果你能真正了解它的话,其实在很多地方我们都可以用得上,那么今天我们就来简单聊聊JS中 reduce ...

  7. LeetCode 817. Linked List Components (链表组件)

    题目标签:Linked List 题目给了我们一组 linked list, 和一组 G, 让我们找到 G 在 linked list 里有多少组相连的部分. 把G 存入 hashset,遍历 lin ...

  8. Oracle 生成sys_guid

    select sys_guid() from dual;select sys_guid() from dual connect by rownum<100

  9. function attributes, MDK

    The keyword format is either of the following: __attribute__((attribute1, attribute2, ...)) __attrib ...

  10. 使用Pyppeteer进行gmail模拟登录

    import asyncio import time from pyppeteer import launch async def gmailLogin(username, password, url ...