2018-12-28 有点累EF明天再写叭=v=

2018-12-29 update EF

B - Simplified mahjong

可以注意到 一段连续的非0序列都可以凑出

就是显然%2=0的可以内部配完 然后%2=1的可以随便向两边传递这个1(就是和旁边的配对改变自己和配对的奇偶性从而使自己变成%2=0旁边变成%2=1)于是就按照0分割统计答案就行了qwq

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 100010
using namespace std; ll a[mxn],n; int main()
{
scanf("%lld",&n);ll ans=0;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
{
ll cnt=a[i];
while(i<n && a[i+1]!=0) cnt+=a[i+1],i++;
ans+=cnt/2;
}
printf("%lld\n",ans);
return 0;
}

C - BBuBBBlesort!

两种操作 翻转长度为2 翻转长度为3

我们用dis[i]表示排名第i的和它所在的初始的位置的距离

翻转长度为2的可以改变一对的奇偶性 然后长度为3的不改变奇偶性

然后把奇数的个数加起来/2就好啦=v=

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 100100
using namespace std; int a[mxn],n,id[mxn];
bool cmp(int x,int y)
{
return a[x]<a[y];
}
int main()
{
scanf("%d",&n);ll ans=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),id[i]=i;
sort(id+1,id+n+1,cmp);
for(int i=1;i<=n;i++) ans+=abs(id[i]-i)&1;
printf("%lld\n",ans/2);
return 0;
}

D - Anticube

我再读错题我就是彪头[flag] = =

读成了选择一段区间 然后思考一下午不会做= =

看题解发现md是随便选几个

这样的话就每个数质因数分解 然后指数全部%3变成最小表示 求一下他的补集 就是 所有指数变成(3-x)%3

这样的话贪心选 自己或补集就可以辣 注意补集=自己只能选一个

发现 ai 10e10 (上pollard-rho啊)

我们可以筛一下10e10的1/3次方以内的质数 然后分解一下

剩下的一定是一个大质数的平方或者大质数

直接判一下就好了=v=

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#define inf 20021225
#define ll long long
#define mxn 100100
using namespace std; map<ll,int> s;
map<ll,bool> h;
bool isp[10100];
ll p[1310],cnt;
void get(int n)
{
isp[1]=1;
for(int i=2;i<=n;i++)
{
if(!isp[i]) p[++cnt]=i;
for(int j=1;j<=cnt&&p[j]*i<=n;j++)
{
isp[p[j]*i]=1;
if(i%p[j]==0) break;
}
}
}
ll a[mxn],b[mxn]; int n;
int main()
{
get(10000);// printf("%d\n",cnt);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
ll q=a[i]; a[i]=b[i]=1ll;
for(int j=1;j<=cnt;j++)
{
int qwq=0;
if(q==1) break;
if(q%p[j]==0)
{
while(q%p[j]==0)
{
q/=p[j];
qwq++;
}
qwq%=3;
if(qwq==1) b[i]*=(ll)p[j]*p[j],a[i]*=p[j];
if(qwq==2) b[i]*=p[j],a[i]*=(ll)p[j]*p[j];
}
}
if(q!=1)
{
ll x=(ll)sqrt(q);
if(x*x == q) b[i]*=x,a[i]*=x*x;
else b[i]*=q*q,a[i]*=q;
}
}
for(int i=1;i<=n;i++) s[a[i]]++;
int ans=0;// printf("%d\n",ans);
for(int i=1;i<=n;i++)
{
if(!h[a[i]])
{
h[a[i]]=h[b[i]]=1;
if(a[i]==b[i]) ans++;
else ans+=max(s[a[i]],s[b[i]]);
}
}
printf("%d\n",ans);
return 0;
}

EF明天更!(两道神题想起来写起来都很烦= =)

E - Sequential operations on Sequence

神仙题做不来

首先可以得到一个结论 a[i]>=a[i+1]的时候只有a[i+1]是有用的 那么我们可以通过单调栈来维护就可以剔除掉没有用的部分

接下来我们来讲神仙操作

我们将操作序列倒过来 倒着进行推导

首先 令s = a[i+1] / a[i] 那么所有的数一定是有一个s倍的增加 然后 r=a[i+1]%a[i] 就是前r个会多出一个零头

对于维护 我们利用两个数组 add 和 mul 分别维护个体增长和倍数级的增长

那么我们可以通过递归来实现 solve(s,l) -> solve(s%st[pos],l*s/st[pos]) 来表示零头和倍数级

那么我们可以通过二分来找到第一个<s的st[pos]那么就可以将这个过程优化到log

然后注意到s每次%一个小于s的数 这样的话最多只会进行log次[类似辗转相除]

这样的话 我们对于一次处理的复杂度是O(lgslgn)

一共n次操作 就是O(nlgnlgs)啦

然后处理的时候 add 是对于每一个位置的一个差分数组 那么最后就是要前缀和啦 mul就是对于每一次操作的每一个位置增长的倍数数组 那么第一次的倍数数组当然是 mul[1] 啦

由于第一次 每一个位置 对应的都是i 每一个数只出现一次 所以就是mul整体 add就是前缀和

最后就是 add的前缀和 + mul[1] 就是答案咯

代码。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 100010
using namespace std; ll a[mxn],stk[mxn];int tp,n,q;
ll cnt[mxn],add[mxn],mul[mxn]; int erf(int l,int r,ll x)
{
int pos=r;
while(l<=r)
{
int mid=l+r>>1;
if(stk[mid] <= x) pos=mid,l=mid+1;
else r=mid-1;
}
return pos;
} void work(ll l,ll k,int x)
{
if(!k) return;
if(k<=stk[1])
{
add[1] += l;
add[k+1] -= l;
return;
}
int pos=erf(1,x,k);
ll tmp = k / stk[pos];
mul[pos] += tmp*l;
work(l,k%stk[pos],pos-1);
} int main()
{
scanf("%d%d",&n,&q);
stk[++tp] = n;
for(int i=1;i<=q;i++)
{
scanf("%lld",&a[i]);
while(tp && stk[tp] >= a[i]) tp--;
stk[++tp] = a[i];
}
mul[tp] = 1;
for(int i=tp;i>=2;i--)
{
ll tmp = stk[i]/stk[i-1];
ll fin = stk[i]%stk[i-1];
mul[i-1] += mul[i]*tmp;
work(mul[i],fin,i-1);
}
for(int i=1;i<=stk[1];i++)
{
add[i] += add[i-1];
printf("%lld\n",mul[1]+add[i]);
}
for(int i=stk[1]+1;i<=n;i++)
printf("0\n");
return 0;
}

F在路上了qwq

F - Fraction of Fractal

非常nb的一个题qwq(才不会说我题意理解了半天= =题意不理解的可以去loj看中文题面会好很多= =)

看了题解才会做 简直是神仙

我们对于一行(或一列)的两端都是黑色的计数分别为 lr ud 对所有的黑色格子计数为cnt

然后会出现4种情况

1.lr>0&&ud>0 这个时候必定是全部联通的 因为原图中保证了四联通 而每一个格子和上下左右是都能联通的 答案是1

2.lr=0&&ud=0 这个时候必定是全部不连通 所以答案是 cnt^(k-1)

3.lr>0&&ud=0 4.lr=0&&ud>0

这两种情况是等价的 因为我们可以把其中一个旋转45°来转换成另一种情况=v=

我们在这里只讨论 ud>0

ud>0那么就是整个图形会有一些上下联通的块把它们连接起来 整个图形就是由一些链组成的

这样的时候我们怎么计数呢?

显然 链是树 所以我们可以根据森林的性质 树数=点数-边数

这样的话我们只需要分开统计链和点就可以了

点很好计数 每次一个黑色格子变成一个黑色联通块 是指数级增长的 就是cnt^(k-1)

边怎么统计呢 这就用到神仙做法了

我们再来统计一个上下接口 就是(a[i-1][j]和a[i][j])都是黑色的情况 计数为eud 这个时候它们之间是会有一条边的

然后我们可以列出柿子 Ek = Ek-1 * cnt + eud*ud^(k-2) 边界条件就是E2=eud

因为 每一个k-1分形里都有ud^(k-2)个联通的1阶分形然后*eud条新边就可以了=v=

然后这个东西构造一波矩阵乘法就可以了w

注意边界数据 k=0 ans=1 = =

代码。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mdn 1000000007
using namespace std; struct matrix{int a[3][3],n;};
inline void init(matrix &a)
{
memset(a.a,0,sizeof(a.a));
}
matrix operator *(matrix a,matrix b)
{
matrix tmp; init(tmp); tmp.n=a.n;
//printf("%d\n",tmp.a[2][2]);
for(int i=1;i<=a.n;i++)
for(int j=1;j<=a.n;j++)
for(int k=1;k<=a.n;k++)
tmp.a[i][j] = ((ll)tmp.a[i][j] +(ll)a.a[i][k]*b.a[k][j]%mdn)%mdn;
return tmp;
} matrix ksm(matrix bs,ll mi)
{
matrix tmp; tmp.n=bs.n; init(tmp);
for(int i=1;i<=tmp.n;i++) tmp.a[i][i]=1;
while(mi)
{
if(mi&1) tmp=tmp*bs;
bs=bs*bs; mi>>=1;
}
return tmp;
}
char mp[1100][1100];
int ud,lr,eud,elr,cnt;
int ksm(int bs,ll mi)
{
int ans=1;
while(mi)
{
if(mi&1) ans=(ll)ans*bs%mdn;
bs=(ll)bs*bs%mdn; mi>>=1;
}
return ans;
}
int main()
{
int h,w;ll k;
scanf("%d%d%lld",&h,&w,&k);
if(k<=1){printf("1\n");return 0;}
for(int i=1;i<=h;i++)
{
scanf("%s",mp[i]+1);
if(mp[i][1] == mp[i][w] && mp[i][1] =='#') lr++;
for(int j=2;j<=w;j++) if(mp[i][j] == mp[i][j-1] && mp[i][j] == '#') elr++;
}
for(int i=2;i<=h;i++)
for(int j=1;j<=w;j++) if(mp[i-1][j] == mp[i][j] && mp[i][j] == '#') eud++;
for(int i=1;i<=w;i++) if(mp[1][i] == mp[h][i] && mp[h][i] == '#') ud++;
for(int i=1;i<=h;i++) for(int j=1;j<=w;j++) cnt+=(mp[i][j]=='#');
if(lr && ud)
{
printf("1\n"); return 0;
}
if(!lr && !ud)
{
printf("%d\n",ksm(cnt,k-1)); return 0;
}
//printf("QAQ");
if(lr) swap(lr,ud),swap(elr,eud); // only ud
matrix ans; ans.n = 2;// printf("%d %d\n",eud,ud);
ans.a[1][1] = cnt; ans.a[1][2] = 0; ans.a[2][1] = 1; ans.a[2][2] = ud;
ans = ksm(ans,k-2);
int fin =(ll)ans.a[1][1]*eud%mdn + (ll)ud*eud%mdn*ans.a[2][1]%mdn;
fin%=mdn; int mis = ksm(cnt,k-1);// printf("%d\n",mis);
//printf("%d %d %d %d\n",ans.a[1][1],ans.a[1][2],ans.a[2][1],ans.a[2][2]);
printf("%d\n",(mis-fin+mdn)%mdn);
return 0;
}

AGC003[BCDEF]题解的更多相关文章

  1. AGC002[BCDEF]题解

    F是计数于是就做(kan ti jie)了= = B - Box and Ball 模拟一下 每个盒子开一个d表示有的球数 可能存在红球的打个标记 传递一下就行了 #include<cstdio ...

  2. AtCoder AGC003 简要题解

    A 首先横向和纵向互相独立,因此只考虑横向的情况. 那么显然只要不只往一边走都一定存在一种构造方式,直接判断即可,复杂度 \(\mathcal{O}(|S|)\). B 首先相邻两个数同时配对两次可以 ...

  3. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  4. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  5. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  6. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  7. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  8. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  9. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

随机推荐

  1. 20180705-Java对象和类

    Java对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态继承封装抽象类对象实例方法消息解析 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个 ...

  2. 实现word在线预览 有php的写法 也有插件似

    <?php //header("Content-type:text/html;charset=utf-8"); //word转html 展示 $lj=$_GET['file' ...

  3. P1970花匠

    传送 首先,这道题据说是一个dp 其次,贪心就能做 我们先来看好想好写的贪心 按照题目来,所有偶数点要么都是凸的,要么都是凹的,不能有凸有凹.我们把每株花的高度都在平面直角坐标系中点出来,再连线.这样 ...

  4. git查看某个文件的提交历史

    1. git log --pretty=oneline 文件名 文件名是文件路径+文件名,输入完整 输入正确后,打印出版本号的列表 2. git show <git提交版本号> <文 ...

  5. Vagrant 手册之多个虚拟机 multi-machine

    原文地址 Vagrant 可以通过一个 Vagrantfile 定义并控制多个客户机.这就是所谓的"multi-machine"多虚拟机环境. 这些机器通常可以协同工作,或者互相关 ...

  6. XML scriptlet 连接数据库

    <%@ page language="java" contentType="text/html" pageEncoding="GBK" ...

  7. Fira Code,可以让不等号!=直接显示出来的字体

    今天看B站某直播间有人写代码C#里一堆不等号直接显示,感觉很神奇,以为是插件还是什么新语法,托人问了下原来是Fira Code字体 https://github.com/tonsky/FiraCode ...

  8. Mimikatz 使用学习

    下载地址 https://github.com/gentilkiwi/mimikatz/ windows:https://download.csdn.net/download/think_ycx/93 ...

  9. Django CORS跨域资源共享

    1,什么是CORS ​ 允许浏览器向跨源(协议 + 域名 + 端口)服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制 2,特点 ​ 1,浏览器自动完成(在请求头中加入特 ...

  10. String.prototype.includes

    if (!String.prototype.includes) {   String.prototype.includes = function(search, start) {     'use s ...