整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


目录

  • The 2019 ICPC China Nanchang National Invitational and International Silk-Road Programming Contest
  • A. Attack
  • B. Polynomial
  • C. Xyjj’s sequence
  • F. Sequence
  • G. Winner
  • H. Another Sequence
  • J. Prefix
  • K. A Good Game
  • L

The 2019 ICPC China Nanchang National Invitational and International Silk-Road Programming Contest

VP地址:https://www.jisuanke.com/contest/20996/challenges

A. Attack

Solution

斯坦纳树板子 + DP即可

Code

#include <bits/stdc++.h>
using namespace std;const int inf = 0x3f3f3f3f;
const int M = 2e3 + 10;
const int N = 40;struct Edge{int to,val;int nxt;
}edges[M];
int head[N],idx = 0;
void add(int u, int v, int c)
{edges[idx] = {v,c,head[u]}, head[u] = idx++;edges[idx] = {u,c,head[v]}, head[v] = idx++;
}int dp[N][500];
int f[500];
map<string, int> mp;
typedef pair<int,int> pii;
priority_queue<pii, vector<pii>, greater<pii>> q;
bool vis[N];void dij(int s)
{memset(vis,0,sizeof(vis));while(q.size()){int u = q.top().second;q.pop();if(vis[u]) continue;vis[u] = 1;for(int i = head[u];~i;i = edges[i].nxt){int v = edges[i].to;int cost = edges[i].val;if(dp[v][s] > dp[u][s] + cost){dp[v][s] = dp[u][s] + cost;q.push({dp[v][s],v});}}}
}bool check(int s)
{for(int i = 0;i < 4;++i){int x = s >> (i * 2) & 1;int y = s >> (i * 2 + 1) & 1;if(x ^ y) return 1;}return 0;
}int main()
{memset(head,-1,sizeof(head));int n,m;scanf("%d%d",&n,&m);for(int i = 1;i <= n;++i){string s;cin >> s;mp[s] = i;}for(int i = 0;i < m;++i){string a, b;int cost;cin >> a >> b >> cost;add(mp[a],mp[b],cost);}memset(dp,0x3f,sizeof(dp));for(int i = 0;i < 8;++i) {string s;cin>>s;dp[mp[s]][1 << i] = 0;}for(int s = 0; s < (1 << 8);++s){for(int i = 1;i <= n;++i){for(int subs = s & (s-1);subs;subs = s & (subs - 1)){dp[i][s] = min(dp[i][s], dp[i][subs] + dp[i][s ^ subs]);}if(dp[i][s] != inf) q.push({dp[i][s],i});}dij(s);}memset(f,0x3f,sizeof(f));for(int s = 0;s < (1 << 8);++s){if(check(s)) continue;for(int i = 1;i <= n;++i) f[s] = min(dp[i][s],f[s]);for(int subs = s & (s-1);subs;subs = s & (subs - 1)){if(check(subs)) continue;f[s] = min(f[subs] + f[s ^ subs], f[s]); }}printf("%d\n",f[(1 << 8) - 1]);  return 0;
}

B. Polynomial

Solution

显然考虑前缀和计算。我们知道若 fff 是一个 nnn 次多项式,其前缀和 sumsumsum 是一个 n+1n+1n+1 次多项式,我们已经有了 n+1n+1n+1 个点,先拉格朗日插值求出第 n+2n+2n+2 个点 f(n+1)f(n+1)f(n+1),然后用这 n+2n+2n+2 个点拉格朗日插值求出 sum(r),sum(l−1)sum(r),sum(l-1)sum(r),sum(l−1) 即可。

Code

#include <bits/stdc++.h>using namespace std;
#define int long long
const int mod = 9999991, N = 5007;int n, m;
int f[N];
int sum[N];
int fact[mod + 10], infact[mod + 10];
int inv[mod + 10];int qpow(int a, int b)
{int res = 1;a %= mod;while(b) {if(b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}void init(int k)
{inv[1] = 1;for(int i = 2; i <= k; ++ i)inv[i] = (mod - mod / i) * inv[mod % i] % mod;infact[0] = 1;for(int i = 1; i <= k; ++ i) {infact[i] = infact[i - 1] * inv[i] % mod;}//cout << infact[k] << endl;
}  int lagrange(int k, int *a, int n)
{int up = 1;for(int i = 0; i <= n; ++ i) {up = up * (k - i) % mod;}//cout << up << "up" << endl;int ans = 0;for(int i = 0; i <= n; ++ i) {int f;if((n - i) & 1) f = -1;else f = 1;int tmp = a[i] * f * infact[i] % mod * infact[n - i] % mod * (up * inv[k - i] % mod) % mod;
//      cout << infact[i] << endl;cout << ans << "ans" << endl;ans = ((ans + tmp) % mod + mod) % mod;}return ans;
}signed main()
{init(mod + 7);int t;scanf("%lld", &t);while(t -- ) {scanf("%lld%lld", &n, &m);for(int i = 0; i <= n; ++ i) {scanf("%lld", &f[i]);}f[n + 1] = lagrange(n + 1, f, n);sum[0] = f[0];for(int i = 1; i <= n + 1; ++ i) {sum[i] = (sum[i - 1] + f[i]) % mod;}while(m -- ) {int l, r;scanf("%lld%lld", &l, &r);if(l <= n && r <= n) {printf("%lld\n", (sum[r] - sum[l - 1] + mod) % mod);}else if(l <= n) {printf("%lld\n", (lagrange(r, sum, n + 1) - sum[l - 1] + mod) % mod);}else printf("%lld\n", (lagrange(r, sum, n + 1) - lagrange(l - 1, sum, n + 1) + mod) % mod);}}return 0;
}

C. Xyjj’s sequence

Solution

先欧拉降幂算出权值(数塔),然后直接DP即可。

Code

#include <bits/stdc++.h>using namespace std;
#define int long long
const int N = 1e5 + 10, p = 1e5 + 3;int v;
int aw[N], bw[N];
int n, m;
int phi[N];int a, b;
int primes[N], cnt;
bool vis[N];int qpow(int a, int b, int mod)
{int res = 1;a %= mod;while(b) {if(b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}void init(int n)
{phi[1] = 1;for(int i = 2; i <= n; ++ i) {if(vis[i] == 0) primes[ ++ cnt] = i, phi[i] = i - 1;for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {vis[i * primes[j]] = true;if(i % primes[j] == 0) {phi[i * primes[j]] = phi[i] * primes[j];break;}phi[i * primes[j]] = phi[i] * (primes[j] - 1);}}
}int dp[2][5001][2];int tower(int num, int p)
{if(p == 1) return 0;if(num == 1) return b % p;return qpow(b, tower(num - 1, phi[p]) + phi[p], p);
}signed main()
{init(1e5 + 7);scanf("%lld%lld", &a, &b);scanf("%lld", &n);for(int i = 1; i <= n; ++ i) {scanf("%lld", &v);aw[i] = qpow(a, tower(v, phi[p]), p);}for(int i = 1; i <= n; ++ i) {scanf("%lld", &v);bw[i] = qpow(a, tower(v, phi[p]), p);}/*for(int i = 1; i <= n; ++ i)printf("%lld\n", aw[i]);for(int i = 1; i <= n; ++ i)printf("%lld\n", bw[i]);*/bw[0] = aw[0] = 0;for(int i = 1;i <= n;++i){int idx = i&1;for(int j = 1;j <= n;++j){dp[idx][j][0] = max(dp[!idx][j][0]+(aw[i]==aw[i-1])*aw[i],dp[idx][j][0]);dp[idx][j][0] = max(dp[!idx][j][1]+(aw[i]==bw[j])*aw[i],dp[idx][j][0]);dp[idx][j][1] = max(dp[idx][j-1][0]+(aw[i]==bw[j])*bw[j],dp[idx][j][1]);dp[idx][j][1] = max(dp[idx][j-1][1]+(bw[j]==bw[j-1])*bw[j],dp[idx][j][1]);}memset(dp[!idx],0,sizeof(dp[!idx]));}cout<<max(dp[n&1][n][1],dp[n&1][n][0])<<endl;
}

F. Sequence

Solution

树状数组维护即可。

Code

#include <bits/stdc++.h>using namespace std;
typedef long long ll;
const int maxn = 100006;
struct BIT
{ll bit[maxn];void modify(int n,ll val,int idx){for(int i = idx;i <= n;i += i&-i)bit[i] ^= val;}ll query(int x){ll ans = 0;for(int i = x;i;i -= i&-i)ans ^= bit[i];return ans;}
}odd,even;
ll a[maxn];void solve()
{static int cs = 0;cs++;memset(&odd,0,sizeof(odd));memset(&even,0,sizeof(even));int n,q;scanf("%d%d",&n,&q);for(int i = 1;i <= n;++i){scanf("%lld",&a[i]);if(i&1)odd.modify(n,a[i],i);else even.modify(n,a[i],i);}printf("Case #%d:\n",cs);while(q--){static int opt,l,r;scanf("%d%d%d",&opt,&l,&r);if(opt==1){if((r-l+1)%2==0)printf("0\n");else{ll ans = 0;if(r&1){ans = odd.query(r)^odd.query(l-1);}else ans = even.query(r)^even.query(l-1);printf("%lld\n",ans);}}else{if(l&1){odd.modify(n,a[l],l);a[l] = r;odd.modify(n,a[l],l);}else{even.modify(n,a[l],l);a[l] = r;even.modify(n,a[l],l);}}}
}int main()
{int t;scanf("%d",&t);while(t--){solve();}
}

G. Winner

Solution

考虑建图,然后缩点即可。

Code

#include <bits/stdc++.h>
using namespace std;typedef pair<int,int> pii;
const int N = 1e5 + 10;
pii a[N],b[N],c[N];struct Edge{int to;int nxt;
}edges[N * 4];
int head[N], idx;void add(int u, int v)
{// printf("%d %d\n",u,v);edges[idx] = {v,head[u]};head[u] = idx++;
}int dfn[N], low[N], tim;
int stk[N], tp = 0;
int ins[N];
int cnt_scc = 0;
int scc_id[N];
vector<int> scc[N];
int in[N];
unordered_map<int,int> ok;void tarjan(int u)
{dfn[u] = low[u] = ++tim;stk[++tp] = u;ins[u] = 1;for(int i = head[u];~i;i = edges[i].nxt){int v = edges[i].to;if(!dfn[v]){tarjan(v);low[u] = min(low[v],low[u]);}else if(ins[v]){low[u] = min(low[u],dfn[v]);}}if(dfn[u] == low[u]){cnt_scc++;int v;do{v = stk[tp--];ins[v] = 0;scc_id[v] = cnt_scc;scc[cnt_scc].push_back(v);}while(u != v);}
}int main()
{memset(head,-1,sizeof(head));int n,m;scanf("%d%d",&n,&m);for(int i = 1;i <= n;++i) scanf("%d",&a[i].first),a[i].second = i;for(int i = 1;i <= n;++i) scanf("%d",&b[i].first),b[i].second = i;for(int i = 1;i <= n;++i) scanf("%d",&c[i].first),c[i].second = i;sort(a+1,a+n+1);sort(b+1,b+n+1);sort(c+1,c+n+1);for(int i = 1;i < n;++i){add(a[i+1].second, a[i].second);add(b[i+1].second, b[i].second);add(c[i+1].second, c[i].second);}for(int i = 1;i <= n;++i){if(!dfn[i]) tarjan(i);}for(int i = 1;i <= n;++i){for(int j = head[i];~j;j = edges[j].nxt){if(scc_id[edges[j].to] != scc_id[i]){in[scc_id[edges[j].to]]++;}}}for(int i = 1;i <= cnt_scc;++i){if(!in[i]){for(auto it : scc[i]){ok[it] = 1;}}}// for(int i = 1;i <= cnt_scc;++i){//     for(auto it : scc[i]){//         printf("%d ",it);//     }//     puts("");// }while(m--){int x;scanf("%d",&x);if(ok[x]) puts("YES");else puts("NO");}return 0;
}

H. Another Sequence

Solution

先用FWT的或运算 O(nlogn)O(nlogn)O(nlogn) 求出数组的值,然后用树状数组维护即可。

Code

#include <bits/stdc++.h>using namespace std;
#define int long long
#define ll long long
const int N = 5e5 + 7;
const int M = 1<<17;
const int MX = 1e5;
int n, m;
int cnta[N], cntb[N], a[N], b[N], c[N], maxx;
int cnt[N];void OR(ll *f, int x = 1)
{for(int o = 2; o <= (1 << 17); o <<= 1) {for(int i = 0, k = o >> 1; i < (1 << 17); i += o) {for(int j = 0; j < k; ++ j) {f[i + j + k] = (f[i + j + k] + f[i + j] * x);}}}
}
int sum[N];int bit[M+5];void modify(int x,int n,int val){for(int i = x;i <= n;i += i&-i)bit[i]+=val;
}
int query(int x){int ans = 0;for(int i = x;i;i -= i&-i)ans += bit[i];return ans;
}void solve()
{using pii = pair<int,int>;vector<int> a;vector<pii> que;int q;scanf("%lld",&q);for(int i = 1,x,y;i <= q;++i){scanf("%lld%lld",&x,&y);a.push_back(y);if(x)a.push_back(x);que.push_back(make_pair(x,y));}sort(a.begin(),a.end());a.erase(unique(a.begin(),a.end()),a.end());for(auto &x:que){if(x.first)x.first = lower_bound(a.begin(),a.end(),x.first)-a.begin()+1;x.second = lower_bound(a.begin(),a.end(),x.second)-a.begin()+1;}for(auto &x:que){if(x.first){modify(x.first,M,1);modify(x.second,M,-1);}else{int val = query(x.second);int id = a[x.second-1];int idx = lower_bound(sum,sum+M,id)-sum;while(idx > 1&&val){val--;idx = sqrt(idx);}printf("%d\n",idx);}}
}   signed main()
{scanf("%lld", &n);for(int i = 1; i <= n; ++ i) {scanf("%lld", &a[i]);cnta[a[i]] ++ ;maxx = max(maxx, a[i]);}for(int i = 1; i <= n; ++ i) {scanf("%lld", &b[i]);cntb[b[i]] ++ ;maxx = max(maxx, b[i]);}OR(cnta);OR(cntb); for(int i = 0; i < 1 << (17); ++ i) {cnt[i] = cnta[i] * cntb[i];}OR(cnt, -1);int ans = 0;/*for(int i = 1; i < 100; ++i){printf("i: %d   num: %d\n",i,cnt[i]);}*/sum[0] = cnt[0];for(int i = 0; i < 1 << (17); ++ i) {//for(int j = 1;j <= cnt[i];++j)printf("%d ",i);sum[i] = sum[i-1]+cnt[i];}solve();/*
1 1 1 2 3 3 4 5 5 5 5 6 7 7 7 8 11 12 12 12 13 14 15 15 15  */}

J. Prefix

Solution

字典树即可。

Code

#include <bits/stdc++.h>
using namespace std;
#define int long longconst int maxn = 2e5+5;
int val[26];int tree[maxn][26];
int n,m,cnt[maxn];
int bit[maxn],tot;
vector<int> endpos[maxn];void modify(int x,int val){for(int i = x;i;i -= i&-i)bit[i] += val;
}
int query(int x,int n){int ans = 0;for(int i = x;i <= n;i += i&-i)ans += bit[i];return ans;
}void Insert(const char *s,int k)
{int root = 0;for(int i = 0;s[i];++i){if(!tree[root][s[i]-'a']){tree[root][s[i]-'a'] = ++tot;}root = tree[root][s[i]-'a'];cnt[root]++;}endpos[root].push_back(k);
}
char s[maxn];
int ans[maxn];void dfs(int now,int num)
{if(endpos[now].size()){for(auto &x:endpos[now])ans[x] = query(num+1+1,m);}modify(num+1,cnt[now]);for(int i = 0;i < 26;++i){if(tree[now][i]){dfs(tree[now][i],1ll*num*val[i]%m);}}modify(num+1,-cnt[now]);
}signed main()
{scanf("%lld%lld",&n,&m);   for(int i = 0;i < 26;++i)scanf("%lld",&val[i]);for(int i = 1;i <= n;++i){scanf("%s",s);Insert(s,i);}dfs(0,1);for(int i = 1;i <= n;++i)printf("%lld ",ans[i]);return 0;
}

K. A Good Game

Solution

显然贪心排序即可。前缀和大的肯定乘上大的数得到的分数最多。

Code

#include <bits/stdc++.h>
using namespace std;const int N = 1e5 + 10;
int v[N];
long long sum[N];struct node{int l,r;long long sum;bool operator<(const node &a)const{return sum < a.sum;}
}op[N];int main()
{int t;scanf("%d",&t);while(t--){int n,m;scanf("%d%d",&n,&m);for(int i = 1;i <= n;++i){scanf("%d",&v[i]);sum[i] = sum[i-1] + v[i];}for(int i = 1;i <= m;++i){scanf("%d%d",&op[i].l,&op[i].r);op[i].sum = sum[op[i].r] - sum[op[i].l-1];}sort(op+1,op+1+m);long long res = 0;for(int i = 1;i <= m;++i){//printf("%d\n",op[i].sum);res += 1ll * op[i].sum * i;}printf("%lld\n",res);} return 0;
}

L

因为太签到了所以计蒜客上没有这道题hhh
看知乎说这道题就是输入三个数求他们的和hhh

签到

2019 ACM - ICPC 全国邀请赛(南昌) 题解(9 / 12)相关推荐

  1. 2019 ACM - ICPC 全国邀请赛(西安)题解(9 / 13)

    The 2019 ACM-ICPC China Shannxi Provincial Programming Contest 目录 The 2019 ACM-ICPC China Shannxi Pr ...

  2. 2019 ACM/ICPC 全国邀请赛(西安)J And And And (树DP+贡献计算)

    Then n - 1n−1 lines follow. ii-th line contains two integers f_{a_i}(1 \le f_{a_i} < i)fai​​(1≤fa ...

  3. 2019 ACM - ICPC 西安邀请赛 B. Product (杜教筛) 简单数论(bushi)

    G.(2019 ACM/ICPC 全国邀请赛(西安)B) Product Weblink https://nanti.jisuanke.com/t/39269 Problem && S ...

  4. 2019 ICPC全国邀请赛(西安)I. Cracking Password(序列检验,BSGS,细节题)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2019 ICPC全国邀请赛(西安)I. Cracking Password Weblink http ...

  5. 2019 ACM - ICPC 上海网络赛 E. Counting Sequences II (指数型生成函数)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  6. 2023年ICPC全国邀请赛(陕西)-Volunteer角度

    2023年ICPC全国邀请赛(陕西)今日开赛.笔者作为只会调试百行出头的js小游戏的弱鸡学生,只能通过担任志愿者来为赛事贡献一份力量了. (图为开幕式现场) 现场的气氛是很好的,热闹是一定的.作为服务 ...

  7. 2019年安徽大学ACM/ICPC实验室新生赛题解

    本文仅作个人收藏学习使用 题目及解析来源牛客竞赛网 //作者:王清楚 //链接:https://ac.nowcoder.com/discuss/351408?type=101&order=0& ...

  8. 2021 ICPC全国邀请赛(西安)太原理工大学收获3枚奖牌

    2021 ICPC 国际大学生程序设计竞赛全国邀请赛,于2021年6月5-6日在西安西北工业大学举行. 这次比赛,太原理工大学共派出3个队伍参加比赛,获得2枚银牌1枚铜牌. 通过这个比赛,锻炼了队伍, ...

  9. 2019 ACM/ICPC 南昌站 G,拉格朗日插值

    题意: 求∑i=1t∑k=xyf(i,k)\sum^t_{i=1}\sum^y_{k=x}f(i,k)i=1∑t​k=x∑y​f(i,k) 其中f(i,k)f(i,k)f(i,k)表示1,2,3,.. ...

最新文章

  1. 三层交换机----VRRP协议学习
  2. Exchange数据库无法装载的问题
  3. 如何用Linux写c程序并编译运行
  4. 洛谷——P1059 明明的随机数
  5. Asp.Net Core 2.2.0-preview1已经发布
  6. 计算机翻译字串符,字符的计算机处理和显示 外文翻译.doc
  7. fedora 忘记root密码
  8. unix-privesc-check提权漏洞快速检测工具
  9. linux用户退出时自动清除last记录,Linux查看用户登陆历史记录(last命令的使用)
  10. linux 进程 转存储,Linux memory management——(进程虚存空间的管理)(转)
  11. 43岁的微软大重组:肢解Windows,拥抱AI,20年功臣离职
  12. 实现Eureka注册发现的高可用
  13. 一位Android大牛的BAT面试心得与经验总结
  14. java sdk qq登录授权_社会化登录分享-QQ SDK接入
  15. android抠图软件,手机抠图软件
  16. PERT图之事件、活动、松弛时间、关键路径
  17. (八)列表操作2(函数番外篇)
  18. 安卓分屏神器_【实用工具】一款鲜为人知的电脑神器,内置300多…找了很久了!...
  19. 证件照的背景颜色转换
  20. 字符串intern()方法详解

热门文章

  1. linux proxy服务器
  2. CentOS 7 中 Systemd详解
  3. 详解JVM内存管理与垃圾回收机制3 - JVM中对象的内存布局
  4. 构建一个运行在Azure虚拟机上的MySQL Spring Boot应用程序
  5. Xcode 小技巧:利用 assets 配置针对不同设备的资源
  6. 用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇
  7. 不安装Oracle使用cx_Oracle
  8. SharePoint 2013 处理videoplayerpage.aspx下的个人图片显示有误问题
  9. repeater中后台动态为控件添加属性
  10. ORACLE HANDBOOK系列之十四:变化通知(Change Notification)