A - Sanitize Hands
题意:
模拟
// Problem: A - Sanitize Hands
// Contest: AtCoder - SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)
// URL: https://atcoder.jp/contests/abc357/tasks/abc357_a
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve()
{int n , m;cin >> n >> m;for(int i = 0 ; i < n ; i++){cin >> a[i];} int cnt = 0;for(int i = 0 ; i < n ; i ++){if(m >= a[i]){cnt ++;m -= a[i];}else{m = 0;}}cout << cnt << endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;//cin>>t;while(t--){solve();}return 0;
}
B - Uppercase and Lowercase
题意:
还是模拟
// Problem: B - Uppercase and Lowercase
// Contest: AtCoder - SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)
// URL: https://atcoder.jp/contests/abc357/tasks/abc357_b
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
void solve()
{int cnt1 = 0;string s;cin >> s; for(auto c : s){if(c >= 'a' && c <= 'z'){cnt1++;}}if(cnt1 * 2 > s.size()){for(auto c : s){if(c >= 'a' && c <= 'z'){cout << c;}else{cout << (char)(c + 32);}}}else{for(auto c : s){if(c >= 'a' && c <= 'z'){cout << (char)(c - 32);}else{cout << (char)c;}} }
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;//cin>>t;while(t--){solve();}return 0;
}
C - Sierpinski carpet
题意:
依旧是模拟..不知道前排大佬怎么能写这么快的
// Problem: C - Sierpinski carpet
// Contest: AtCoder - SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)
// URL: https://atcoder.jp/contests/abc357/tasks/abc357_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
vector<vector<string>>v(7 , vector<string>(10101));
void solve()
{int n;cin >> n;for(int i = 1 ; i <= (int)pow(3 , n) ; i ++){cout << v[n][i] <<endl;}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t = 1;v[0][1] = '#';for(int i = 1 ; i < 7 ; i ++){int pre = (int)pow(3 , i - 1);for(int j = 1 ; j <= 3 * pre ; j ++){if((j - 1) / pre != 1){for(int t = 0 ; t < 3 ; t ++){v[i][j] += v[i - 1][(j - 1) % pre + 1]; }}else{v[i][j] += v[i - 1][(j - 1) % pre + 1];for(int t = 0 ; t < pre ; t ++){v[i][j] += '.';}v[i][j] += v[i - 1][(j - 1) % pre + 1];}}}while(t--){solve();}return 0;
}
D - 88888888
思路:将答案拆成加和的形式:假设N的位数为,那么最终答案为,然后可以将 提出来之后,其余的是一个等比数列,因此有等比数列求和公式将答案化简为:
注意n*x可能爆longlong
// Problem: D - 88888888
// Contest: AtCoder - SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)
// URL: https://atcoder.jp/contests/abc357/tasks/abc357_d
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 998244353;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
#define int unsigned long long
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
LL qpow(LL a , LL b)//快速幂
{LL sum=1;while(b){if(b&1){sum=sum*a%mod;}a=a*a%mod;b>>=1;}return sum;
}
void solve()
{cin >> n;int tmp = n;int len = 0;while(tmp){len ++;tmp /= 10;}int t = n % mod;int fenzi = qpow(qpow(10 , n) , len) - 1 + mod;fenzi %= mod;int bei = qpow(10 , len) - 1 + mod;int tbei = qpow(bei , mod - 2);int ans = t;t *= fenzi;t %= mod;t *= tbei;t %= mod;cout << t;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;//cin>>t;while(t--){solve();}return 0;
}
E - Reachability in Functional Graph
题意:
思路:将有向图通过SCC缩点形成一个有向无环图(DAG), 然后思考答案:同一个强连通分量的点两两互相连通,然后与该连通分量相连的所有点与该连通分量上的所有点相连通,因此本题变成了DAG图上DP,直接逆拓扑序走一遍。考虑单独存储每一个强连通分量上的点,与能够连接到该连通分量上的点即可。 (SCC知识快忘记的差不多了..只记得bel从大到小就是逆拓扑序)
// Problem: E - Reachability in Functional Graph
// Contest: AtCoder - SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)
// URL: https://atcoder.jp/contests/abc357/tasks/abc357_e
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
#define int long long
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){for(int i = 0 ; i <= n ; i ++){a[i] = 0;}
}
struct SCC {int n;std::vector<std::vector<int>> adj;//邻边std::vector<int> stk;//存储同一个SCCstd::vector<int> dfn, low, bel;//dfn : dfs的时间戳 low : 子树能跳到的最上方的点 bel : 结点位于哪块强连通分量上 int cur, cnt;SCC() {}SCC(int n) {init(n);}void init(int n) {this->n = n;adj.assign(n, {});dfn.assign(n, -1);low.resize(n);bel.assign(n, -1);stk.clear();cur = cnt = 0;}void addEdge(int u, int v) {adj[u].push_back(v);}void dfs(int x) {dfn[x] = low[x] = cur++;stk.push_back(x);for (auto y : adj[x]) {if (dfn[y] == -1) {dfs(y);low[x] = std::min(low[x], low[y]);} else if (bel[y] == -1) {low[x] = std::min(low[x], dfn[y]);}}if (dfn[x] == low[x]) {int y;do {y = stk.back();bel[y] = cnt;stk.pop_back();} while (y != x);cnt++;}}std::vector<int> work() {for (int i = 0; i < n; i++) {if (dfn[i] == -1) {dfs(i);}}return bel;}
};void solve()
{int n;cin >> n;SCC scc(n + 5);for(int i = 1 ; i <= n ; i ++){int x;cin >> x;if(x != i){scc.addEdge(i , x);}}vector<int>t = scc.work();vector<int>dp(n + 5 , 0);vector<int>cnt(n + 5 , 0);vector<int>chan[n + 5];int ma = -1;for(int i = 1; i <= n ; i ++){//cout << t[i] << endl;cnt[t[i]]++;chan[t[i]].pb(i);ma = max(ma , t[i]);}int ans = 0;vector<int>vis(n + 5, 0);for(int i = ma ; i >= 1 ; i --){int tmp = cnt[i];ans += cnt[i] * cnt[i];ans += dp[i] * cnt[i];cnt[i] += dp[i];vector<int>path;for(auto it : chan[i]){int next;if(scc.adj[it].size() != 0){next = scc.adj[it][0];}else{continue;}int belo = scc.bel[next];if(!vis[belo]){path.pb(belo);vis[belo] = 1;dp[belo] += cnt[i];}}for(auto it : path){vis[it] = 0;}}//cout << cnt[3] << endl;cout << ans;
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;while(t--){solve();}return 0;
}
F - Two Sequence Queries
题意:
思路:很明显的线段树题目(在这几天做的题里面算简单的了)。一个区间需要维护的信息有:区间点的个数(act)、区间中A数组的和(asum)、区间中B数组的和(bsum)、以及区间A*B的和(tot)。区间合并非常简单,全部相加即可。主要考虑tag怎么设置,可以发现,若区间A都加上X,那么其asum += act * X , tot += bsum * X。反之B区间也是一样。然后本题就完成了
// Problem: F - Two Sequence Queries
// Contest: AtCoder - SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)
// URL: https://atcoder.jp/contests/abc357/tasks/abc357_f
// Memory Limit: 1024 MB
// Time Limit: 5000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define int long long
#define endl '\n'
const LL maxn = 4e05+7;
const LL N = 5e05+10;
#define i64 long long
const LL mod = 998244353;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){return b > 0 ? gcd(b , a % b) : a;
}LL lcm(LL a , LL b){return a / gcd(a , b) * b;
}
template<class Info, class Tag>
struct LazySegmentTree {const int n;std::vector<Info> info;std::vector<Tag> tag;LazySegmentTree(int n) : n(n), info(4 << std::__lg(n)), tag(4 << std::__lg(n)) {}LazySegmentTree(std::vector<Info> init) : LazySegmentTree(init.size()) {std::function<void(int, int, int)> build = [&](int p, int l, int r) {if (r - l == 1) {info[p] = init[l];return;}int m = (l + r) / 2;build(2 * p, l, m);build(2 * p + 1, m, r);pull(p);};build(1, 0, n);}void pull(int p) {info[p] = info[2 * p] + info[2 * p + 1];}void apply(int p, const Tag &v) {info[p].apply(v);tag[p].apply(v);}void push(int p) {apply(2 * p, tag[p]);apply(2 * p + 1, tag[p]);tag[p] = Tag();}void modify(int p, int l, int r, int x, const Info &v) {if (r - l == 1) {info[p] = v;return;}int m = (l + r) / 2;push(p);if (x < m) {modify(2 * p, l, m, x, v);} else {modify(2 * p + 1, m, r, x, v);}pull(p);}void modify(int p, const Info &v) {modify(1, 0, n, p, v);}Info rangeQuery(int p, int l, int r, int x, int y) {if (l >= y || r <= x) {return Info();}if (l >= x && r <= y) {return info[p];}int m = (l + r) / 2;push(p);return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);}Info rangeQuery(int l, int r) {return rangeQuery(1, 0, n, l, r);}void rangeApply(int p, int l, int r, int x, int y, const Tag &v) {if (l >= y || r <= x) {return;}if (l >= x && r <= y) {apply(p, v);return;}int m = (l + r) / 2;push(p);rangeApply(2 * p, l, m, x, y, v);rangeApply(2 * p + 1, m, r, x, y, v);pull(p);}void rangeApply(int l, int r, const Tag &v) {return rangeApply(1, 0, n, l, r, v);}void half(int p, int l, int r) {if (info[p].act == 0) {return;}if ((info[p].min + 1) / 2 == (info[p].max + 1) / 2) {apply(p, {-(info[p].min + 1) / 2});return;}int m = (l + r) / 2;push(p);half(2 * p, l, m);half(2 * p + 1, m, r);pull(p);}void half() {half(1, 0, n);}
};
struct Tag {i64 adda = 0;i64 addb = 0;void apply(Tag t) {adda += t.adda;adda %= mod;addb += t.addb;addb %= mod;}
};
struct Info {int asum = 0;int bsum = 0;int tot = 0;int act = 0;void apply(Tag t) {asum += (t.adda * act) % mod;asum %= mod;tot += (bsum * t.adda) % mod;tot %= mod;bsum += (t.addb * act) % mod;bsum %= mod;tot += ((asum % mod) *( t.addb % mod)) % mod;tot %= mod;}
};
Info operator + (Info a, Info b) {Info c;c.asum = a.asum + b.asum;c.asum %= mod;c.bsum = a.bsum + b.bsum;c.bsum %= mod;c.act = a.act + b.act;c.act %= mod;c.tot = a.tot + b.tot;c.tot %= mod;return c;
}
void solve()
{int n , m;cin >> n >> m;vector<Info>v(n);for(int i = 0 ; i < n ; i ++){cin >> v[i].asum;}for(int i = 0 ; i < n ; i ++){cin >> v[i].bsum;}for(int i = 0 ; i < n ; i ++){v[i].act = 1;v[i].tot = v[i].asum * v[i].bsum;v[i].tot %= mod;}LazySegmentTree <Info , Tag> seg(v);for(int i = 0 ; i < m; i ++){int op;cin >> op;if(op == 1){int l , r , x;cin >> l >> r >> x;Tag tmp;tmp.adda = x;seg.rangeApply(l - 1 , r , tmp);}else if(op == 2){int l , r , x;cin >> l >> r >>x;Tag tmp;tmp.addb = x;seg.rangeApply(l - 1 , r , tmp);}else{int l , r;cin >> l >> r;cout << seg.rangeQuery(l - 1 , r).tot << endl;}}
}
signed main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout.precision(10);int t=1;//cin>>t;while(t--){solve();}return 0;
}