传送门

\(A\)

咕咕

  1. const int N=1005;
  2. char s[N];int val[N],n;
  3. int main(){
  4. scanf("%s",s+1),n=strlen(s+1);
  5. fp(i,1,n)++val[s[i]];
  6. if((val['W']!=0)^(val['E']!=0))return puts("No"),0;
  7. if((val['S']!=0)^(val['N']!=0))return puts("No"),0;
  8. return puts("Yes"),0;
  9. }

\(B\)

不难发现每个数能和自己匹配就和自己匹配,最多只会和左边右边分别匹配一次,那么我们记\(f_{i,0/1}\)表示考虑\(i\),且\(i\)留下了\(0/1\)个的方案数,从左往右\(dp\)即可

  1. typedef long long ll;
  2. const int N=1e5+5;const ll inf=1e18;
  3. int a[N],k,n;ll f[N][2],res;
  4. int main(){
  5. scanf("%d",&n);
  6. fp(i,1,n)scanf("%d",&a[i]);
  7. memset(f,0xef,sizeof(f));
  8. f[0][0]=0;
  9. fp(i,1,n){
  10. if(!a[i])f[i][0]=max(f[i-1][0],f[i-1][1]);
  11. else{
  12. f[i][0]=max(f[i-1][0]+(a[i]>>1),max(f[i-1][1]+(a[i]>>1),f[i-1][1]+((a[i]-1)>>1)+1));
  13. f[i][1]=max(f[i-1][0]+((a[i]-1)>>1),max(f[i-1][1]+((a[i]-1)>>1),a[i]>=2?f[i-1][1]+((a[i]-2)>>1)+1:-inf));
  14. }
  15. }
  16. printf("%lld\n",max(f[n][0],f[n][1]));
  17. return 0;
  18. }

\(C\)

重新标号之后发现一直进行操作\(2\)的话奇数位上的只能一直在奇数位上,那么一个偶数要到奇数位上至少需要经过一次\(1\)操作,把所有偶数在奇数位上和奇数在偶数位上的个数分别记下来,两个取较大值就是答案了

  1. const int N=1e5+5;
  2. int b[N],d[N],st[N],c[2],n;
  3. int main(){
  4. // freopen("testdata.in","r",stdin);
  5. scanf("%d",&n);
  6. fp(i,1,n)scanf("%d",&b[i]),d[i]=b[i];
  7. sort(d+1,d+1+n);
  8. fp(i,1,n)st[i]=lower_bound(d+1,d+1+n,b[i])-d,c[st[i]&1]+=((st[i]&1)^(i&1));
  9. printf("%d\n",max(c[0],c[1]));
  10. return 0;
  11. }

\(D\)

先把每个数所有的三次因子除掉,这样之后两个相等的数就在同一个等价类,除了\(1\)要特判之外,其它每个数对应的不能选的数是唯一的,在分解质因子的过程中能顺便把它给算出来,然后两边取较大值加入就可以了

分解质因子的时候如果枚举到\(10^5\)显然会炸,那么我们是枚举到\(3000\)次左右,那么剩下的数要么是一个质数要么是一个质数的平方,分类讨论一下即可

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fi first
  5. #define se second
  6. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  7. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  8. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  9. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  10. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  11. using namespace std;
  12. typedef long long ll;
  13. const int N=3005;
  14. bitset<N>vis;int p[N],m;
  15. void init(int n=3000){
  16. fp(i,2,n){
  17. if(!vis[i])p[++m]=i;
  18. for(R int j=1;j<=m&&1ll*i*p[j]<=n;++j){
  19. vis[i*p[j]]=1;
  20. if(i%p[j]==0)break;
  21. }
  22. }
  23. }
  24. const int M=1e5+5;
  25. ll a[M];int n,res;
  26. map<ll,int>mp;
  27. typedef map<ll,int>::iterator IT;
  28. int main(){
  29. // freopen("testdata.in","r",stdin);
  30. init();
  31. scanf("%d",&n);
  32. R ll tmp;
  33. fp(i,1,n){
  34. scanf("%lld",&a[i]);
  35. for(R int j=1;j<=m&&1ll*p[j]*p[j]*p[j]<=a[i];++j){
  36. tmp=1ll*p[j]*p[j]*p[j];
  37. while(a[i]%tmp==0)a[i]/=tmp;
  38. }
  39. ++mp[a[i]];
  40. }
  41. for(IT it=mp.begin();it!=mp.end();++it){
  42. if(it->fi==1)continue;
  43. R ll x=it->fi,y=1;
  44. fp(j,1,m)if(x%p[j]==0){
  45. R int c=0;
  46. while(x%p[j]==0)x/=p[j],++c;
  47. (c&1)?(y*=p[j]*p[j]):(y*=p[j]);
  48. }
  49. if(x!=1){
  50. tmp=sqrt(x);
  51. tmp*tmp==x?(y*=tmp):(y*=x*x);
  52. }
  53. if(!mp.count(y)||it->fi<y)res+=max(it->se,mp.count(y)?mp[y]:0);
  54. }
  55. if(mp[1])++res;
  56. printf("%d\n",res);
  57. return 0;
  58. }

\(E\)

首先对于一个\(q_i\),如果它后面有一个小于等于它的数那么它就没有用了,所以先用单调栈把\(q_i\)变成递增的(包括一开始的\(n\))

然后考虑暴力,对于一个\(q_i\)到\(q_{i+1}\),相当于是把\(q_i\)复制若干遍之后再加上\(q_i\)的一个前缀形成了\(q_{i+1}\),那么我们从后往前做,记\(cnt_{i}\)表示\(q_i\)被重复的次数,以及一个栈\(tmp\)代表后面所有的多出来的前缀,那么对于\(i\),它的\(cnt\)就等于原来的重复次数乘上\(cnt_{i+1}\),以及对于之前的每一个多余的前缀\(tmp_{j}\),加上一个\(tmp_{j}/q_{i}*tc_{j}\)(其中\(tc_{j}\)表示\(j\)这个前缀被重复的次数),然后\(tmp_j\)变成\(tmp_j\%q_i\),这样就可以算出\(cnt_i\)了,而它多出来的前缀就是\(q_{i}\%q_{i-1}\),且这个前缀的重复次数就是\(cnt_{i}\)

然而这样暴力的话是\(O(n^2)\)的,考虑优化,对于一个前缀,它会给前面的\(cnt_{i}\)造成贡献当且仅当\(q_i\leq tmp_j\),也就是说取模之后\(tmp_j\)会变小。那么对于一个前缀,我们可以二分找到它左边第一个小于等于它的位置,然后给那个位置加上对应的贡献,之后一直找就行了。因为一个数有效的取模次数不超过\(O(\log n)\),所以总复杂度为\(O(n\log n\log q_i)\)

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  8. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  9. using namespace std;
  10. typedef long long ll;
  11. const int N=1e5+5;
  12. ll q[N],st[N],cnt[N],a[N],s[N],x;int top,n,m;
  13. void ins(R ll x,R ll p,R int pos){
  14. R int k;
  15. while(x>=st[1]){
  16. k=lower_bound(st+1,st+1+pos,x+1)-st-1;
  17. s[k]+=x/st[k]*p,x%=st[k],pos=k-1;
  18. }
  19. a[x]+=p;
  20. }
  21. int main(){
  22. // freopen("testdata.in","r",stdin);
  23. scanf("%d%d",&n,&m),top=0;
  24. st[++top]=n;
  25. fp(i,1,m){
  26. scanf("%lld",&x);
  27. while(top&&x<=st[top])--top;
  28. st[++top]=x;
  29. }
  30. fp(i,1,top-1)cnt[i]=st[i+1]/st[i];
  31. cnt[top]=cnt[top+1]=1;
  32. fd(i,top,2)cnt[i]=cnt[i]*cnt[i+1]+s[i],ins(st[i]%st[i-1],cnt[i],i-1);
  33. cnt[1]=cnt[1]*cnt[2]+s[1];
  34. fd(i,n,1)a[i]+=a[i+1];
  35. fp(i,1,n)printf("%lld\n",(i<=st[1]?cnt[1]+a[i]:0));
  36. return 0;
  37. }

\(F\)

先判断这个网格左右拼接和上下拼接是否会导致联通块个数的减少,分别记为\(flag1\)和\(flag2\),并且为了方便起见我们默认初始图形为给出的网格(也就是事实上的\(1\)阶分形)为\(0\)阶分形

如果两个都不成立,证明每次分形都不会减少联通块,记网格中总的黑点个数为\(sz\),那么\(k\)次分形之后会使联通块个数变为\(sz^k\)

如果两个都成立,因为黑点四联通,所以每次分形之后联通块个数都不会减少,最后答案为\(1\)

剩下两种情况中,不失一般性,假设左右拼接会导致联通块个数减少而上下不会,记\((i,j)\)和\((i,j+1)\)同时为黑点的数量为\(p\),以及\((i,1)\)和\((i,m)\)同时为黑点的数量为\(q\)

假设\(k\)次分形之后联通块个数为\(ans\),那么第\(k+1\)次分形后,联通块个数会变为\(ans\times sz-p\times q^{k-1}\)(这个柿子可以画个图理解)

那么就好办了,一开始答案是\(1\),把柿子全部展开变成形如\(((1\times sz-p\times q^{0})\times sz -p\times q^{1})...\),变成\(sz^k-p\times \sum_{i=0}^{k-1}q^{i}sz^{k-1-i}\),把后面那个当成一个等比数列求和就行了

  1. //quming
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  8. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  9. using namespace std;
  10. typedef long long ll;
  11. const int P=1e9+7;
  12. inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
  13. inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
  14. inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
  15. inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
  16. int ksm(R int x,R ll y){
  17. R int res=1;
  18. for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
  19. return res;
  20. }
  21. int kkk(R int x,R ll y){
  22. R int res=1,d=1;
  23. for(;y;y>>=1,d=mul(x+1,d),x=mul(x,x))(y&1)?res=add(mul(res,x),d):0;
  24. return res;
  25. }
  26. const int N=1005;
  27. char mp[N][N],t[N][N];int n,m,sz,p,ss,res;ll k;
  28. inline int ck1(){R int res=0;fp(i,1,n)res+=(mp[i][1]=='#'&&mp[i][m]=='#');return res;}
  29. inline int ck2(){R int res=0;fp(j,1,m)res+=(mp[1][j]=='#'&&mp[n][j]=='#');return res;}
  30. int main(){
  31. scanf("%d%d%lld",&n,&m,&k);
  32. if(k<=1)return puts("1"),0;
  33. --k;
  34. fp(i,1,n)scanf("%s",mp[i]+1);
  35. fp(i,1,n)fp(j,1,m)sz+=mp[i][j]=='#';
  36. int sz1=ck1(),sz2=ck2();
  37. if(sz1&&sz2)return puts("1"),0;
  38. if(!sz1&&!sz2)return printf("%d\n",ksm(sz,k)),0;
  39. if(sz2){
  40. fp(i,1,n)fp(j,1,m)t[j][i]=mp[i][j];
  41. swap(n,m);
  42. fp(i,1,n)fp(j,1,m)mp[i][j]=t[i][j];
  43. swap(sz1,sz2);
  44. }
  45. fp(i,1,n)fp(j,1,m-1)ss+=(mp[i][j]=='#'&&mp[i][j+1]=='#');
  46. // printf("%d %d %d\n",sz,ss,sz1);
  47. res=mul(ksm(sz,k-1),kkk(mul(sz1,ksm(sz,P-2)),k-1));
  48. res=dec(ksm(sz,k),mul(ss,res));
  49. printf("%d\n",res);
  50. return 0;
  51. }

AtCoder Grand Contest 003题解的更多相关文章

  1. AtCoder Grand Contest 003

    AtCoder Grand Contest 003 A - Wanna go back home 翻译 告诉你一个人每天向哪个方向走,你可以自定义他每天走的距离,问它能否在最后一天结束之后回到起点. ...

  2. AtCoder Grand Contest 017 题解

    A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...

  3. AtCoder Grand Contest 003 D - Anticube

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_d 题目大意: 给定\(n\)个数\(s_i\),要求从中选出尽可能多的数,满足任意两个数之积 ...

  4. AtCoder Grand Contest 003 E - Sequential operations on Sequence

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_e 题目大意 一串数,初始为\(1\sim N\),现有\(Q\)个操作,每次操作会把数组长度 ...

  5. AtCoder Grand Contest 003 F - Fraction of Fractal

    题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_f 题目大意: 给定一个\(H×W\)的黑白网格,保证黑格四连通且至少有一个黑格 定义分形如下 ...

  6. Atcoder Grand Contest 054 题解

    那天晚上由于毕业晚会与同学吃饭喝酒没打 AGC,第二天稍微补了下题,目前补到了 E,显然 AGC 的 F 对于我来说都是不可做题就没补了(bushi A 简单题,不难发现如果我们通过三次及以上的操作将 ...

  7. AtCoder Grand Contest 030题解

    第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...

  8. AtCoder Grand Contest 031题解

    题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...

  9. [Atcoder Grand Contest 003] Tutorial

    Link: AGC003 传送门 A: 判断如果一个方向有,其相反方向有没有即可 #include <bits/stdc++.h> using namespace std; ]; map& ...

随机推荐

  1. unbuntu 16.04 MS-Celeb-1M + alexnet + pytorch

    最近被保研的事情搞的头大,拖了半天才勉强算结束这个了.从熟悉unbantu 16.04的环境(搭个翻墙的梯子都搞了一上午 呸!)到搭建python,pytorch环境.然后花了一个上午熟悉py的基本语 ...

  2. isolate 通信

    main.dart import 'package:flutter/material.dart'; import 'package:flutter_isolate/flutter_isolate.da ...

  3. UML回顾暨课程总结

    本文作为OO的最后一次博客作业,主要回顾了第四单元的架构设计和本学期的心路历程. 本单元架构设计 UML1 ​ 第一次作业的主要内容是解析mdj格式输入,记录特定数据并支持针对类.属性和方法等的查询功 ...

  4. Python学习资料收集

    1.Learn Python the hard way 2.Google's Python lesson 3.Python最佳实践 4.Full Stack Python 5.explore flas ...

  5. Apache Commons FileUpload实现文件上传

    一.Apache Commons-FileUpload简介 Apache Commons是一个专注于可重用Java组件的所有方面的 Apache 项目. Apache Commons项目由三个部分组成 ...

  6. (在客户端)https抓包解密

    (一)原理分析 https的数据包是用对称秘钥(https协议协商出来的随机数)加密后的密文. 对称秘钥在传输线路上是密文的(被非对称加密过),但是在client.server端是明文的(因为要用于加 ...

  7. OSI7层模型和网络排错、网络安全

    1.OSI7层模型和网络排错 7层模型和网络排错 序号 层 网络排错举例 措施 1 物理层故障 查看链接状态发送和接收数据包 2 数据链路层故障 MAC冲突ADSL欠费网速没法协商一致计算机连接到错误 ...

  8. 通过标签名获得td和tr

    <tr node="123445"> <td> <input type=button name="dak"> </td ...

  9. python内置异常层次

    内置异常 BaseException # 所有异常的基类 +-- SystemExit # 解释器请求退出 +-- KeyboardInterrupt # 用户中断执行(通常是输入^C) +-- Ge ...

  10. Android笔记(六十八) Fragment总结

    Fragment的产生: 为了适应各种尺寸的屏幕,谷歌推出Fragment,可以把Fragment成Activity的一个组成部分,它拥有自己的生命周期.可以接收并处理用户的各种事件,还可以动态的增删 ...