AGC编号越小越水????

AGC003

A - Wanna go back home

相对方向要么一起有要么一起没有

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 500005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
string s;
map<char,int> zz;
void Solve() {
cin >> s;
for(int i = 0 ; i < s.length() ; ++i) zz[s[i]] = 1;
if((zz['W'] ^ zz['E']) & 1) {puts("No");return;}
if((zz['N'] ^ zz['S']) & 1) {puts("No");return;}
puts("Yes");
} int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

B - Simplified mahjong

先把每个卡自己都配对,取模2

然后剩余的单张卡如果距离下一张单张卡之间的卡都有对子,那么拆掉这些对子可以获得加1的贡献,扫一遍就好了

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,A[MAXN],pa[MAXN];
int64 ans = 0;
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) {
read(A[i]);
ans += A[i] / 2;
pa[i] = A[i] / 2;
A[i] %= 2;
}
int pre = -1;
for(int i = 1 ; i <= N ; ++i) {
if(A[i]) {
if(pre == -1) pre = i;
else {pre = -1;++ans;}
}
else {
if(!pa[i]) pre = -1;
}
}
out(ans);enter;
} int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

C - BBuBBBlesort!

因为三个交换不改变每个数所在位置的奇偶性,如果一个数的目标位置和自己所在位置的奇偶性不同那么就需要一次Op1

计算所有当前位置和目标位置奇偶性不同的位置除二即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int cnt[2],A[MAXN],N,B[MAXN];
map<int,int> zz;
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) {read(A[i]);B[i] = A[i];}
sort(B + 1,B + N + 1);
for(int i = 1 ; i <= N ; ++i) zz[B[i]] = i;
for(int i = 1 ; i <= N ; ++i) {
if(((zz[A[i]] ^ i) & 1) != 0) cnt[i & 1]++;
}
out(cnt[0]);enter;
} int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

D - Anticube

先用\(\sqrt[3]{10^{10}}\)给所有的数的质数指数幂取模3

初始答案设成N,统计1的个数是cnt,若cnt不为0,答案减掉cnt - 1

然后分析一下,每个数只有唯一的一个各个质数指数不超过3的数和这个数配对使得这个数成为立方数

如何找这个数呢,质因数分解显然会超时

但是分析一下,如果只有一个质数的话,我们特判掉,然后我们默认用配对的数中的小的和大的配,这样的话质数最大的范围可以这么考虑

如果这个数是\(pq\)的话,\(p,q\)都是质数,和它配对的是\(p^{2}q^{2}\),这个数也要在\(10^{10}\)的范围内,所以至多只有一个数大于\(\sqrt[4]{10^{10}}\)

如果这个数是\(p^2q\),配对的是\(pq^{2}\),那么至多只有一个数大于\(\sqrt[3]{10^{10}}\)

且最大的那个质数不大于\(10^{5}\)

所以我们预处理出\(10^5\)以内每个数是不是质数用来判断,质数分解的时候只需要用\(\sqrt[3]{10^{10}}\)以内的

这样大概不到1s就过了

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N;
int64 S[MAXN],pre[1000005];
int prime[MAXN],tot,cnt;
bool nonprime[MAXN];
map<int64,int> zz;
int s[7] = {4,7,11,29,47,71,87};
vector<int64> v;
int64 mul(int64 a,int64 b,int64 MOD) {
int64 res = 0,t = a;
while(b) {
if(b & 1) res = (res + t) % MOD;
t = (t + t) % MOD;
b >>= 1;
}
return res;
}
int64 fpow(int64 a,int64 c,int64 MOD) {
int64 res = 1,t = a;
while(c) {
if(c & 1) res = mul(res,t,MOD);
t = mul(t,t,MOD);
c >>= 1;
}
return res;
}
bool check(int64 s,int t,int64 MOD) {
if(s == 1) return true;
for(int i = 1 ; i <= t ; ++i) {
int64 nxt = mul(s,s,MOD);
if(nxt == 1) {
if(s == MOD - 1) return true;
return false;
}
}
return false;
}
bool miller_rabin(int64 x) {
int t = 0;int64 tmp = x - 1;
while(tmp % 2 == 0) {++t;tmp /= 2;}
for(int i = 0 ; i < 7 ; ++i) {
if(!check(fpow(s[i],tmp,x),t,x)) return false;
}
return true;
}
void Solve() {
read(N);
for(int64 i = 1 ; i <= 1000000 ; ++i) pre[i] = i * i * i;
for(int64 i = 2 ; i <= 100000 ; ++i) {
if(!nonprime[i]) {
prime[++tot] = i;
}
for(int j = 1 ; j <= tot ; ++j) {
if(i * prime[j] > 100000) break;
nonprime[i * prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
int ans = N;
for(int i = 1 ; i <= N ; ++i) {
read(S[i]);
for(int j = 1 ; j <= 500 ; ++j) {
if(pre[prime[j]] > S[i]) break;
while(S[i] % pre[prime[j]] == 0) S[i] /= pre[prime[j]];
}
if(S[i] == 1) ++cnt;
else {zz[S[i]]++;v.pb(S[i]);}
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
if(cnt > 1) ans -= (cnt - 1);
for(auto num : v) {
int64 t = sqrt(num);
if(t * t == num) continue;
if(num <= 100000 && !nonprime[num]) {ans -= min(zz[num],zz[num * num]);}
else {
int64 x = num;
int64 op = 1;
for(int i = 1 ; i <= 500 ; ++i) {
if(prime[i] > 3500 || prime[i] > x) break;
if(x % prime[i] == 0) {
int c = 0;
while(x % prime[i] == 0) {x /= prime[i];++c;}
c = 3 - c;
op = op * prime[i];
if(op > 1e10) goto fail;
if(c == 2) op = op * prime[i];
if(op > 1e10) goto fail;
}
}
if(x != 1) {
if(x <= 100000) {
if(nonprime[x]) goto fail;
for(int i = 0 ; i < 2 ; ++i) {
op = op * x;
if(op > 1e10) goto fail;
}
}
else {
goto fail;
}
} if(op > num) ans -= min(zz[num],zz[op]);
}
fail:;
}
out(ans);enter;
} int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

E - Sequential operations on Sequence

用一个单调栈,每次来一个操作弹出到第一个小于它的,然后我们得到一个新的操作序列这个和原来的操作序列结果是一样的

这个时候我们每次操作都是递增的,第一个大小是a的话,那么第一个序列就是1,2,3,4...a

然后我们把栈顶的统计次数设为1,sta[i - 1]的统计次数要加上是\(sta[i] / sta[i - 1] * cnt[i]\)

然后我们有一个余数是\(sta[i] \% sta[i - 1]\)

我们二分找到第一个小于这个余数的序列,计算余数除这个序列的次数乘上本序列统计次数加到这个序列上,然后余数取模序列长度,直到余数小于等于一个序列大小,此时若为b,ans[b] += cnt[i],之后统计一个后缀和就是答案

因为每次取模余数都会减少一半,所以复杂度是$Q \log{max{ q{i}}} \log N $

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N,Q,top;
int64 sta[MAXN];
int64 cnt[MAXN],ans[MAXN];
void Solve() {
read(N);read(Q);
sta[++top] = N;
int64 p;
for(int i = 1 ; i <= Q ; ++i) {
read(p);
while(top && sta[top] >= p) --top;
sta[++top] = p;
}
cnt[top] = 1;
for(int i = top ; i >= 1 ; --i) {
if(i != top) cnt[i] += cnt[i + 1] * (sta[i + 1] / sta[i]);
if(i == 1) {ans[sta[1]] += cnt[1];continue;}
int64 r = sta[i] % sta[i - 1];
while(r > sta[1]) {
int t = upper_bound(sta + 1,sta + top + 1,r) - sta - 1;
cnt[t] += cnt[i] * (r / sta[t]);
r %= sta[t];
}
ans[r] += cnt[i];
}
for(int i = N ; i >= 1 ; --i) ans[i] += ans[i + 1];
for(int i = 1 ; i <= N ; ++i) {
out(ans[i]);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();mahjong
return 0;
}

F - Fraction of Fractal

简单分析一下,如果初始图形复制一份左右拼接不上,上下拼接不上,那就是黑色个数的\(K - 1\)次方

如果左右拼上,上下拼上,那就是1

如果只有左右拼上,初始认为每一个黑格子都会新形成一个联通块,那么新来一个右边会减少1,此时如果左右拼上的行很多,那么过了一个level之后,这些行也会相连接导致联通块减少

所以对于每个方块统计它右边有没有方块,记为h,以及能起始和终止都有黑格子的行有几个,记为a,总联通块个数记为b

那么\(f(k + 1) = bf(k) - h * a^{k - 1}\)

这个用矩阵乘法优化一下就好了

如果只有上下拼上是同理的

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 +c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 1000000007;
int H,W,all,h,c;
int64 K;
char s[1005][1005];
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
void update(int &x,int y) {
x = inc(x,y);
}
struct Matrix {
int f[2][2];
Matrix() {memset(f,0,sizeof(f));}
friend Matrix operator * (const Matrix &a,const Matrix &b) {
Matrix c;
for(int i = 0 ; i < 2 ; ++i) {
for(int j = 0 ; j < 2 ; ++j) {
for(int k = 0 ; k < 2 ; ++k) {
update(c.f[i][j],mul(a.f[i][k],b.f[k][j]));
}
}
}
return c;
}
}a,ans;
Matrix fpow(Matrix x,int64 c) {
Matrix res,t = x;
res.f[0][0] = res.f[1][1] = 1;
while(c) {
if(c & 1) res = res * t;
t = t * t;
c >>= 1;
}
return res;
}
int fpow(int x,int64 c) {
int64 res = 1,t = x;
while(c) {
if(c & 1) res = mul(res,t);
t = mul(t,t);
c >>= 1;
}
return res;
}
void Solve() {
read(H);read(W);read(K);
if(K == 0 || K == 1) {puts("1");return;}
for(int i = 1 ; i <= H ; ++i) scanf("%s",s[i] + 1);
for(int i = 1 ; i <= H ; ++i) {
for(int j = 1 ; j <= W ; ++j) {
if(s[i][j] == '#') {
++all;
if(s[i][j + 1] == '#') ++h;
if(s[i + 1][j] == '#') ++c;
}
}
}
bool f1 = 0;int c1 = 0;
for(int i = 1 ; i <= H ; ++i) {
if(s[i][1] == '#' && s[i][W] == '#') {f1 = 1;++c1;}
}
bool f2 = 0;int c2 = 0;
for(int i = 1 ; i <= W ; ++i) {
if(s[1][i] == '#' && s[H][i] == '#') {f2 = 1;++c2;}
}
if(f1 && f2) {puts("1");return;}
if(!f1 && !f2) {
out(fpow(all,K - 1));enter;return;
}
if(f1) {
a.f[1][0] = MOD - h;
a.f[1][1] = c1;
}
else if(f2) {
a.f[1][0] = MOD - c;
a.f[1][1] = c2;
}
a.f[0][0] = all;
ans = fpow(a,K - 1);
out(inc(ans.f[0][0],ans.f[1][0]));enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【AtCoder】AGC003的更多相关文章

  1. 【AtCoder】ARC092 D - Two Sequences

    [题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...

  2. 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring

    [题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...

  3. 【AtCoder】ARC 081 E - Don't Be a Subsequence

    [题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...

  4. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

  5. 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT

    [题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...

  6. 【AtCoder】ARC067 F - Yakiniku Restaurants 单调栈+矩阵差分

    [题目]F - Yakiniku Restaurants [题意]给定n和m,有n个饭店和m张票,给出Ai表示从饭店i到i+1的距离,给出矩阵B(i,j)表示在第i家饭店使用票j的收益,求任选起点和终 ...

  7. 【AtCoder】ARC095 E - Symmetric Grid 模拟

    [题目]E - Symmetric Grid [题意]给定n*m的小写字母矩阵,求是否能通过若干行互换和列互换使得矩阵中心对称.n,m<=12. [算法]模拟 [题解]首先行列操作独立,如果已确 ...

  8. 【Atcoder】AGC022 C - Remainder Game 搜索

    [题目]C - Remainder Game [题意]给定n个数字的序列A,每次可以选择一个数字k并选择一些数字对k取模,花费2^k的代价.要求最终变成序列B,求最小代价或无解.n<=50,0& ...

  9. 【Atcoder】AGC 020 B - Ice Rink Game 递推

    [题意]n个人进行游戏,每轮只保留最大的a[i]倍数的人,最后一轮过后剩余2人,求最小和最大的n,或-1.n<=10^5. [算法]递推||二分 [题解]令L(i),R(i)表示第i轮过后的最小 ...

随机推荐

  1. DP的优化

    参考资料: 李煜东<算法竞赛进阶指南> 斜率优化 形如: \(f[i] = min\{f[j]+val(i,j)\}\)的dp,多项式\(val(i,j)\)包含\(i,j\)的乘积项 引 ...

  2. redis系列(三):python操作redis

    1.安装包 pip install redis 2.使用 # -*- coding: utf-8 -*- # @Time : 18-12-7 下午4:33 # @Author : Felix Wang ...

  3. qtableview 表格风格设置

    1.窗体无边框? tableView->setFrameShape(QFrame::NoFrame); 2.表格内容无边框? tableView->setShowGrid(false); ...

  4. CSPS模拟75&76

    感觉自己还是太菜了... 最近考试一直想不出来正解.难受(然而蒟蒻的博客没人看也要不来小猪peiqi的图) 模拟75:血炸... 考场上推了快两个小时的T1式子,然后心态炸裂,然后我也不知道自己干了什 ...

  5. 第一章:Python数据分析前的基础铺垫

    本节概要 - 数据类型 - 数据结构 - 数据的常用操作方法 数据类型 基础铺垫 定义 我们搞数据时,首先要告诉Python我们的数据类型是什么 数值型:直接写一个数字即可 逻辑型:True,Fals ...

  6. pandas常用操作命令大全

    网上的有个别不对 实际敲了一下  有补充了点常用的环境IDE anaconda  python3.7 在这个速查手册中,我们使用如下缩写: df:任意的Pandas DataFrame对象 s:任意的 ...

  7. 关于在vue项目中使用wangEditor

    1,vue中安装wangEditor 使用的npm安装 npm install wangeditor --save 2,创建公用组件 在components中创建wangEnduit文件夹 组件内容为 ...

  8. 通过xshell在本地win主机和远程linux主机传输文件

    1.下载和安装xshell此处不再介绍 2.安装lrzsz的软件 yum install lrzsz 3.通过xshell上传文件 只需要在XShell的菜单中点击File – Transfer – ...

  9. maven的pom报错web.xml is missing and <failOnMissingWebXml> is set to true

    错误信息:web.xml is missing and <failOnMissingWebXml> is set to true 解决办法:https://blog.csdn.net/si ...

  10. ubuntu上面Parity 安装

      sudo wget https://raw.githubusercontent.com/paritytech/parity/master/scripts/parity.service -O /et ...