[Atcoder Grand Contest 003] Tutorial
Link:
A:
判断如果一个方向有,其相反方向有没有即可
#include <bits/stdc++.h> using namespace std;
char s[];
map<char,bool> mp;
int main()
{
scanf("%s",s);
for(int i=;i<strlen(s);i++) mp[s[i]]=true;
if(mp['S']==mp['N']&&mp['E']==mp['W']) puts("Yes");
else puts("No");
return ;
}
Problem A
B:
贪心最大化利用即可
#include <bits/stdc++.h> using namespace std;
int n,dat[];
long long res=;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&dat[i]);
for(int i=;i<=n-;i++)
{
res+=dat[i]/;dat[i]%=;
if(dat[i+]>dat[i]) dat[i+]-=dat[i],res+=dat[i];
}
res+=dat[n]/;
printf("%lld",res);
return ;
}
Problem B
C:
可以将两个操作转换为:
1、交换两个相邻的数
2、交换两个中间相间一个的数
由于只要求操作1的最小数,可以发现调整好所有数的序号的奇偶性就能用操作2完成任务
因此求出原序号为奇数,排序后序号为偶数的数的个数即可(原偶现奇的个数与其相同)
#include <bits/stdc++.h> using namespace std;
int n,dat[],id[]; bool cmp(int a,int b)
{return dat[a]<dat[b];}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&dat[i]),id[i]=i;
sort(id+,id+n+,cmp);
int res=;
for(int i=;i<=n;i++)
if((id[i]&)&&!(i&)) res++;
printf("%d",res);
return ;
}
Problem C
D:
思路类似于 [Codeforces#480 D] ,只不过将平方改成了立方
要判断两个数的积为立方,可以将每个数的各个质因数次幂$mod 3$化简后再判断
于是我们求出每个数化简后的结果,统计出现次数,同时求出化简后的数的补数
最后在一个数及其补数中选择个数更多的那一组即可(特判:如果化简后为1只能算一个)
实现的难点在质因数分解……
由于$n\le 10^{10}$,肯定不能求出$n$以内的所有质数
于是要先将$10^{\frac{10}{3}}$内的质因数分解掉,保证剩下的质因数的次幂不会超过2次
实际上,剩下的数只有3种情况,分类讨论就好了:
1、$p^2$ 2、$p$ 3、$p*q$ ($p,q$为质数)
这样就能在$O(1)$的时间内计算大于$10^{\frac{10}{3}}$的质因数的化简结果及其补数了
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
const int MAXN=1e5+;
int n,pri[],vis[],tot,res=;
ll x[MAXN],y[MAXN],t;
map<ll,int> mp,avl; ll cube(int a){return 1ll*a*a*a;}
ll sqr(int a){return 1ll*a*a;}
int main()
{
for(int i=;i<=;i++)
{
if(!vis[i]) pri[++tot]=i;
for(int j=;j<=tot&&i*pri[j]<=;j++)
{
vis[i*pri[j]]=;
if(i%pri[j]==) break;
}
} scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%lld",&t);x[i]=y[i]=;
for(int j=;cube(pri[j])<=t;j++)
{
int cnt=;
while(t%pri[j]==) t/=pri[j],cnt++;
if(cnt%==) x[i]*=pri[j],y[i]*=sqr(pri[j]);
else if(cnt%==) x[i]*=sqr(pri[j]),y[i]*=pri[j];
}
x[i]*=t;mp[x[i]]++;
y[i]*=sqr(sqrt(t))==t?sqrt(t):sqr(t);
} for(int i=;i<=n;i++)
if(!avl[x[i]])
{
avl[x[i]]=avl[y[i]]=;
if(x[i]==) res++;
else res+=max(mp[x[i]],mp[y[i]]);
}
printf("%d",res);
return ;
}
Problem D
如果操作为除法/取模,且要枚举$n$个除数/模数时,
学会较小数暴力,较大数分类讨论的方式(如 [ARC060 D])
E:
首先可以将$dat$序列改为单调递增的,其他项明显是多余的
通过观察发现每一项可以由之前的项重复、组合而成(可能留有小于$len[1]$的后缀)
于是我们令$cnt[i]$为第$i$项被重复的总次数,对于从后往前每一个$i$:
每次二分找到最大的小于$dat[i]$的$dat[j]$,那么第$j$项可以多重复$dat[i]/dat[j]*cnt[i]$次
接下来将$dat[i]$mod$dat[j]$,寻找下一个重复项
由于一个数$mod$比自己小的数明显最多进行$log(n)$次,因此复杂度为$O(n*log(n))$
由于每项在整块整块分解后仍可能有小于$len[1]$的后缀,需要另外统计
为了保证时间复杂度,且由于该后缀一定连续,因此差分统计就好了
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
const int MAXN=1e5+;
int n,q,tot;
ll res[MAXN],dat[MAXN],cnt[MAXN]; int Query(ll x,int r)
{
int ret=-,l=;
while(l<=r)
{
int mid=(l+r)>>;
if(dat[mid]<=x) ret=mid,l=mid+;
else r=mid-;
}
return ret;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=q;i++) scanf("%lld",&dat[i]);
dat[]=n;//如果最小值大于n要添加n
for(int i=;i<=q;i++)
{
while(tot>=&&dat[i]<dat[tot]) tot--;
dat[++tot]=dat[i];
} cnt[tot]=;
for(int i=tot;i>=;i--)
{
ll k=dat[i],pos=Query(k,i-);
while(pos>=)
{
cnt[pos]+=(k/dat[pos])*cnt[i];
k=k%dat[pos];pos=Query(k,pos-);
}
res[]+=cnt[i];res[k+]-=cnt[i];
}
for(int i=;i<=n;i++)
res[i]+=res[i-],printf("%lld\n",res[i]);
return ;
}
Problem E
F:
%%%LCA的题解:https://loj.ac/article/189
一眼看上去完全不可做的题(好像对我而言所有题都这样)
但先进行大的分类后其实会发现明朗很多
令矩阵中有色点数为$cnt$,上下/左右相邻的有色点对数分别为$pv,ph$
令原矩阵上下/左右拼接后能连通的列数/行数分别为$sv,sh$
1、如果$sv,sh$都大于零,明显全部连通
2、如果$sv,sh$都为零,明显答案为$cnt^{k-1}$
3、如果$sv,sh$中恰有一个大于零,需要递推:
将最终矩阵中每一个初始矩阵视为一个点,两点相连通则视为有一条边
由于最终状态不可能有环,求连通块的个数,其实就是求点数与边数的差
根据上面求出的量,可以写出如下的递推式:
$V_k=V_{k-1}*cnt$
$E_k=E_{k-1}*cnt+pv(h)*sv(h)$
对于这样的式子矩乘优化就好了
#include <bits/stdc++.h> using namespace std;
typedef long long ll;
const int MOD=1e9+,MAXN=;
struct matrix
{
ll p[][];
matrix(){memset(p,,sizeof(p));}
void init(){p[][]=p[][]=;}
friend matrix operator * (const matrix &a,const matrix &b)
{
matrix ret;
for(int i=;i<;i++)
for(int j=;j<;j++)
for(int k=;k<;k++)
(ret.p[i][j]+=a.p[i][k]*b.p[k][j]%MOD)%=MOD;
return ret;
}
friend matrix quick_pow(matrix a,ll b)
{
matrix ret;ret.init();
for(;b;b>>=,a=a*a)
if(b&) ret=ret*a;
return ret;
}
}; char s[MAXN][MAXN];
ll k;
int n,m,cnt,pv,ph,sv,sh;
ll quick_pow(ll a,ll b)
{
ll ret=;
for(;b;b>>=,a=a*a%MOD)
if(b&) ret=ret*a%MOD;
return ret;
} int main()
{
scanf("%d%d%lld",&n,&m,&k);
if(k<=) return puts(""),;
for(int i=;i<=n;i++) scanf("%s",s[i]+);
for(int i=;i<=n;i++) for(int j=;j<=m;j++)
if(s[i][j]=='#')
{
cnt++;
pv+=(s[i][j]==s[i+][j]);
ph+=(s[i][j]==s[i][j+]);
}
for(int i=;i<=m;i++) sv+=(s[][i]=='#'&&s[n][i]=='#');
for(int i=;i<=n;i++) sh+=(s[i][]=='#'&&s[i][m]=='#'); if(sv&&sh) return puts(""),;
else if(!sv&&!sh) return printf("%lld",quick_pow(cnt,k-)),;
else
{
matrix t;t.p[][]=cnt;t.p[][]=(sv?pv:)+(sh?ph:);t.p[][]=sv+sh;
t=quick_pow(t,k-);printf("%lld",(t.p[][]-t.p[][]+MOD)%MOD);
}
return ;
}
Problem F
[Atcoder Grand Contest 003] Tutorial的更多相关文章
- AtCoder Grand Contest 003
AtCoder Grand Contest 003 A - Wanna go back home 翻译 告诉你一个人每天向哪个方向走,你可以自定义他每天走的距离,问它能否在最后一天结束之后回到起点. ...
- AtCoder Grand Contest 003 D - Anticube
题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_d 题目大意: 给定\(n\)个数\(s_i\),要求从中选出尽可能多的数,满足任意两个数之积 ...
- AtCoder Grand Contest 003 E - Sequential operations on Sequence
题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_e 题目大意 一串数,初始为\(1\sim N\),现有\(Q\)个操作,每次操作会把数组长度 ...
- AtCoder Grand Contest 003 F - Fraction of Fractal
题目传送门:https://agc003.contest.atcoder.jp/tasks/agc003_f 题目大意: 给定一个\(H×W\)的黑白网格,保证黑格四连通且至少有一个黑格 定义分形如下 ...
- [Atcoder Grand Contest 004] Tutorial
Link: AGC004 传送门 A: …… #include <bits/stdc++.h> using namespace std; long long a,b,c; int main ...
- Atcoder Grand Contest 003 F - Fraction of Fractal(矩阵乘法)
Atcoder 题面传送门 & 洛谷题面传送门 Yet another AGC F,然鹅这次就没能自己想出来了-- 首先需注意到题目中有一个条件叫做"黑格子组成的连通块是四联通的&q ...
- [Atcoder Grand Contest 002] Tutorial
Link: AGC002 传送门 A: …… #include <bits/stdc++.h> using namespace std; int a,b; int main() { sca ...
- [Atcoder Grand Contest 001] Tutorial
Link: AGC001 传送门 A: …… #include <bits/stdc++.h> using namespace std; ; ]; int main() { scanf(& ...
- AtCoder Grand Contest 003题解
传送门 \(A\) 咕咕 const int N=1005; char s[N];int val[N],n; int main(){ scanf("%s",s+1),n=strle ...
随机推荐
- 【BZOJ 1409】 Password 数论(扩展欧拉+矩阵快速幂+快速幂)
读了一下题就会很愉快的发现,这个数列是关于p的幂次的斐波那契数列,很愉快,然后就很愉快的发现可以矩阵快速幂一波,然后再一看数据范围就......然后由于上帝与集合对我的正确启示,我就发现这个东西可以用 ...
- 在JS中,一切东东其实都是对象
对象是组成JavaScript的基本单元,在JS中,一切东东其实都是对象,而且功能非常强大,它不仅风格独特,功能也与众不同. 一.引用(reference) 引用的概念是JS的基础之一,它是指向对象实 ...
- hibernate连接mysql,自动建表失败
hibernate的列名使用了mysql的关键字.
- jquery从零起步学
html: <HTML> <head> <meta http-equiv="content-type" content="text/html ...
- c# vs2008报表
1. 做报表没做几次,第一次做的都忘记了,还好今天做一下就把报表弄成功了.报表中“参数字段”是可以变的,就是说需要自己赋值或者是要计算的.而在苏据库字段里面的是固定的值.不需要计算(注:有的字段查询出 ...
- 知问前端——日历UI(一)
日历(datepicker)UI,可以让用户更加直观的.更加方便的输入日期,并且还考虑不同国家的语言限制,包括汉语. 调用datepicker()方法 $('#date').datepicker(); ...
- 【BZOJ】1799: [Ahoi2009]self 同类分布
[题意]给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数.1 ≤ a ≤ b ≤ 10^18 [算法]数位DP [题解] 感觉这种方法很暴力啊. 枚举数位和1~162(不能枚举0,不然会模 ...
- centOS 7 部署samba
部署samba **每个用户有自己的目录,可以浏览内容,也可以删除** 清空防火墙规则 [root@bogon ~]# iptables -F 安装samba [root@bogon ~]# yum ...
- Codeforces 362E Petya and Pipes 费用流建图
题意: 给一个网络中某些边增加容量,增加的总和最大为K,使得最大流最大. 费用流:在某条边增加单位流量的费用. 那么就可以2个点之间建2条边,第一条给定边(u,v,x,0)这条边费用为0 同时另一条边 ...
- windows中Appium-desktop配合夜神模拟器的使用
1.安装Android SDK并配好环境 ANDROID_HOME :C:\Users\18810\AppData\Local\Android\Sdk path:%ANDROID_HOME%\plat ...