Educational Codeforces Round 56 Editorial
A.Dice Rolling
题意:Mishka 有一个六面的骰子,每面分别为 2 ~ 7,而且 Mishka 是欧皇,可以控制自己每次掷到的数字。Mishka 现在想掷若干次骰子,使得掷到的点数总和为 x,请求出任意一种掷骰子的方案,并输出掷骰子的次数。由于 Mishka 很好奇不同数字的方案,所以有 t 组询问。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+10; int a[maxn],n,t,x; int main() {scanf("%d",&t);for(int i=1;i<=t;i++){scanf("%d",&x);if(x%2==0){printf("%d\n",x/2);}else {printf("%d\n",x/2);}} }
View Code
B.Letters Rearrangin
题意:t 组询问,每次给你一个字符串,将其重新排列使其成为一个非回文串,如果无解则输出 -1 。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+10; int a[1010],n,t,x,flag; char s[1010]; int main() {scanf("%d",&t);for(int i=1;i<=t;i++){memset(a,0,sizeof(a));flag=0;scanf("%s",&s);int l=strlen(s);for(int i=0;i<l;i++){if(a[s[i]]==0) flag++;a[s[i]]++;}if(flag==1) {printf("-1\n");continue;}for(int i=1;i<=128;i++){for(int j=1;j<=a[i];j++)printf("%c",i);}printf("\n");} }
View Code
C.Mishka and the Last Exam
题意:有一个长度为 n(n 为偶数)的数列 a1..n,ai<=ai+1,bi=ai+an-i+1, 现在告诉你 n 和 b1..n/2,求a1..n 。
思路:采用贪心的策略,对于任意一个bi,让a n-i+1尽可能大,ai尽能小,所以从中间开始贪心。(注意long long)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=3e5+10; long long a[maxn],b[maxn]; int n,t,x,flag,l,r; char s[1010]; int main() {scanf("%d",&n);for(int i=1;i<=n/2;i++) scanf("%I64d",&b[i]);l=n/2;r=n/2+1;a[l]=a[r]=b[l]/2;a[r]+=b[l]%2;for(int i=n/2-1;i>=1;i--){if(b[i]-a[l]<a[r]) {a[r+1]=a[r];a[l-1]=b[i]-a[r+1];}else{a[l-1]=a[l];a[r+1]=b[i]-a[l-1];}l--;r++;}for(int i=1;i<=n;i++) printf("%I64d ",a[i]); }
View Code
D.Beautiful Graph
题意:给你一个 n 个点 m 条边的无向图。你需要给每个点一个点权,使得每条边连接的两个点点权奇偶不同。点权的值域为 {1,2,3}。请求出方案数对 998244353 取模的结果。图中没有重边或自环。
思路:要做一次 bfsbfs 染色并判断是否能完成染色即可bfs染色,加个快速幂即可
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int p=998244353; const int maxn=6e5+10; const int maxm=6e5+10; int x,y,z,l=0,t,n,m; int link[maxm],w[maxm],ne[maxm],first[maxn],fa[maxn]; int f[maxn]; int ans,flag,ana; long long an=1; LL quick_mod(LL a,LL b) {LL ans=1;a%=p;while(b){if(b&1) {ans=ans*a%p;b--;}b>>=1;a=a*a%p;}return ans; } void add(int x,int y) {link[++l]=y;ne[l]=first[x];first[x]=l; } int dfs(int x,int fa,bool col) {f[x]=col;ana++;if(col==0)ans++;//printf("%d %d\n",x,fa);for(int i=first[x];i;i=ne[i]){if(link[i]==fa) continue;if(f[link[i]]==-1){if (dfs(link[i],x,!col)) ;else return 0; }else {if(f[link[i]]!=(!col)) return 0;}}return 1; } int getfa(int x) {if(x==fa[x]) return x;return fa[x]=getfa(fa[x]); } int main() {scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);an=1;for(int i=1;i<=n;i++) f[i]=-1,first[i]=0,fa[i]=i;l=0;for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);int fx=getfa(x),fy=getfa(y);fa[fx]=fy;add(x,y);add(y,x);}flag=1;for(int i=1;i<=n;i++){ans=0;ana=0;if(fa[i]==i){if(dfs(i,0,0)){//printf("%d %d %d\n",i,ana,ans);an=an*(quick_mod(2,ans)+quick_mod(2,ana-ans))%p;}else {flag=0;break;}}}if(!flag) printf("0\n");else printf("%I64d\n",an);} }
View Code
E.Intersection of Permutations
题意:给你长度为n的两个序列,有m个询问,1 la ra lb rb 表示查询a数组[la,ra]区间内和b数组[lb,rb]区间内相同的数的个数,2 x y,交换 b数组 的第 x 位与第 y 位
思路1:用 pa[i]表示 i这个数在第一个排列中出现的位置,pb[i]表示 i这个数在第二个排列中出现的位置,那么容易发现问题变成了二维数点问题,cdq 分治离线统计答案即可
#include<bits/stdc++.h> using namespace std; const int N=2e5+5; int n,m,ta[N],tb[N],pa[N],pb[N],ans[N],tot,f[N],cnt; struct node{bool fx;int x,y,k,id,tim;node(int f=0,int x=0,int y=0,int k=0,int i=0,int t=0):fx(f),x(x),y(y),k(k),id(i),tim(t) {}bool operator< (const node &b) const{return x<b.x||(x==b.x&&tim<b.tim);} }a[(N<<2)+N],b[(N<<2)+N]; void add(int x,int k){for(;x<=n;x+=(x&-x))f[x]+=k;} int query(int x){int ret=0;for(;x;x-=(x&-x))ret+=f[x];return ret;} void solve(int l,int r) {if(l>=r) return;int mid=(l+r)>>1,p0=l,p1=mid+1;for(int i=l;i<=r;i++)if(!a[i].fx&&a[i].tim<=mid) add(a[i].y,a[i].k);else if(a[i].fx&&a[i].tim>mid) ans[a[i].id]+=a[i].k*query(a[i].y);for(int i=l;i<=r;i++)if(!a[i].fx&&a[i].tim<=mid) add(a[i].y,-a[i].k);for(int i=l;i<=r;i++)if(a[i].tim<=mid) b[p0++]=a[i];else b[p1++]=a[i];for(int i=l;i<=r;i++) a[i]=b[i];solve(l,mid);solve(mid+1,r); } int main() {scanf("%d",&n);scanf("%d",&m);for(int i=1;i<=n;i++) scanf("%d",&ta[i]),pa[ta[i]]=i;for(int i=1;i<=n;i++) scanf("%d",&tb[i]),pb[tb[i]]=i;for(int i=1;i<=n;i++)a[++cnt]=node(0,pa[i],pb[i],1,0,cnt);for(int i=1,op,x1,y1,x2,y2,w1,w2;i<=m;i++){scanf("%d",&op);if(op==1){tot++;scanf("%d",&x1);scanf("%d",&x2);scanf("%d",&y1);scanf("%d",&y2);x1--;y1--;a[++cnt]=node(1,x2,y2,1,tot,cnt);a[++cnt]=node(1,x1,y2,-1,tot,cnt);a[++cnt]=node(1,x2,y1,-1,tot,cnt);a[++cnt]=node(1,x1,y1,1,tot,cnt);}else{scanf("%d",&w1);scanf("%d",&w2);y1=w1;x1=pa[tb[w1]];y2=w2;x2=pa[tb[w2]];swap(tb[w1],tb[w2]);a[++cnt]=node(0,x2,y2,-1,0,cnt);a[++cnt]=node(0,x1,y1,-1,0,cnt);a[++cnt]=node(0,x2,y1,1,0,cnt);a[++cnt]=node(0,x1,y2,1,0,cnt);}} sort(a+1,a+1+cnt);solve(1,cnt);for(int i=1;i<=tot;i++) printf("%d\n",ans[i]);return 0; }
View Code
思路2:时间线段树+扫描线
上一棵时间线段树。将一个点覆盖在它出现的时间区间内,一个询问则在从单独代表这个询问的时间的线段树节点到线段树的根的路径上都放一个,遍历线段树的时候,
对于每个节点上放的询问们和点们,都做一遍扫描线。
#include<bits/stdc++.h> using namespace std; #define RI register int int read() {int q=0;char ch=' ';while(ch<'0'||ch>'9') ch=getchar();while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();return q; } const int N=200005; int n,m,qcnt; int a[N],X[N],T[N],ans[N],s[N]; struct node{int x,Y1,Y2,id;}; vector<node> tr[N<<2];void insq(int x,int s,int t,int i,node k) {//将询问放在时间线段树上tr[i].push_back(k); if(s==t) return;int mid=(s+t)>>1;if(x<=mid) insq(x,s,mid,i<<1,k);else insq(x,mid+1,t,(i<<1)|1,k); } void insp(int l,int r,int s,int t,int i,node k) {//将点放在时间线段树上if(l<=s&&t<=r) {tr[i].push_back(k);return;}int mid=(s+t)>>1;if(l<=mid) insp(l,r,s,mid,i<<1,k);if(mid+1<=r) insp(l,r,mid+1,t,(i<<1)|1,k); }bool cmp(node A,node B) {return A.x==B.x?A.id==0:A.x<B.x;} int lowbit(int x) {return x&(-x);} void add(int x,int v) {while(x<=n) s[x]+=v,x+=lowbit(x);} int query(int x) {int re=0; while(x) re+=s[x],x-=lowbit(x); return re;} void work(int s,int t,int i) {sort(tr[i].begin(),tr[i].end(),cmp);//扫描线int sz=tr[i].size();for(RI j=0;j<sz;++j) {if(!tr[i][j].id) add(tr[i][j].Y1,1);else {int kl=query(tr[i][j].Y2)-query(tr[i][j].Y1-1);if(tr[i][j].id<0) ans[-tr[i][j].id]-=kl;else ans[tr[i][j].id]+=kl;}}for(RI j=0;j<sz;++j) if(!tr[i][j].id) add(tr[i][j].Y1,-1);if(s==t) return;int mid=(s+t)>>1;work(s,mid,i<<1),work(mid+1,t,(i<<1)|1); }int main() {int op,X1,Y1,X2,Y2;n=read(),m=read();for(RI i=1;i<=n;++i) a[read()]=i;for(RI i=1;i<=n;++i) X[i]=a[read()],T[i]=0;for(RI i=1;i<=m;++i) {op=read();if(op==1) {X1=read(),X2=read(),Y1=read(),Y2=read(),++qcnt;insq(i,0,m,1,(node){X1-1,Y1,Y2,-qcnt});insq(i,0,m,1,(node){X2,Y1,Y2,qcnt});}else {X1=read(),X2=read();insp(T[X1],i-1,0,m,1,(node){X[X1],X1,0,0});insp(T[X2],i-1,0,m,1,(node){X[X2],X2,0,0});swap(X[X1],X[X2]),T[X1]=T[X2]=i;}}for(RI i=1;i<=n;++i) insp(T[i],m,0,m,1,(node){X[i],i,0,0});work(0,m,1);for(RI i=1;i<=qcnt;++i) printf("%d\n",ans[i]);return 0; }
View Code
F. Vasya and Array
题意:给你一个长度为n的序列,一个正整数K,和长度len,序列中的数都是1-k或者为-1,-1表示可以填任何数。让你在-1的地方填数,使得没有长度?len的相等数字。
思路:DP,DP[i][j]表示填到第i为的数字为j的方案数,S[i]为DP[i][j](1<=j<=k)注意转移
#include <bits/stdc++.h> #define md 998244353 #define maxn 100001 #define max(a,b) (a>b?a:b) #define maxk 101 int n,k,len,a[maxn]; int f[maxn][maxk],s[maxn],cnt[maxn][maxk]; void inc(int &a,int b){a=((a+b>=md)?a+b-md:a+b);} int main(){scanf("%d%d%d",&n,&k,&len);for (register int i=1;i<=n;++i)scanf("%d",&a[i]);for (register int i=1;i<=n;++i)for (register int j=1;j<=k;++j)inc(cnt[i][j],cnt[i-1][j]+(a[i]==j||a[i]==-1));for (register int i=1;i<=n;++i){for (register int j=1;j<=k;++j){if (!(a[i]==j||a[i]==-1)) continue;int add=1;if (i>1) add=s[i-1];inc(f[i][j],add);bool ok=i>=len;int l=max(1,i-len+1);ok&=(cnt[i][j]-cnt[l-1][j]==len);if (!ok) continue;if (i==len) {inc(f[i][j],md-1);continue;}int sum=f[i-len][j];inc(sum,md-s[i-len]);inc(f[i][j],sum);}for (register int j=1;j<=k;++j)inc(s[i],f[i][j]);}printf("%d\n",s[n]); }
View Code
G.Multidimensional Queries
题意:给你 n 个 k 维的点 ,求区间内两个点曼哈顿距离的最大值。
思路:习惯性的把曼哈顿距离的绝对值拆出来,用二进制表示31 的二进制表示是 11111,表示 5维的一个点的坐标加入的正负情况都为正(即 x[1] - y[1] + x[2] - y[2] + x[3] - y[3] + x[4] - y[4] + x[5] - y[5]
用线段树维护
#include <bits/stdc++.h> #define Fast_cin ios::sync_with_stdio(false), cin.tie(); #define rep(i, a, b) for(register int i = a; i <= b; i++) #define per(i, a, b) for(register int i = a; i >= b; i--) #define DEBUG(x) cerr << "DEBUG" << x << " >>> " << endl; using namespace std;typedef unsigned long long ull; typedef long long ll;template <typename _T> inline void read(_T &f) {f = 0; _T fu = 1; char c = getchar();while(c < '0' || c > '9') { if(c == '-') fu = -1; c = getchar(); }while(c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }f *= fu; }template <typename T> void print(T x) {if(x < 0) putchar('-'), x = -x;if(x < 10) putchar(x + 48);else print(x / 10), putchar(x % 10 + 48); }template <typename T> void print(T x, char t) {print(x); putchar(t); }const int N = 2e5 + 5;struct ele { int f[32]; };struct Node {int l, r; ele val; }p[N << 2];int t[N][5]; int n, m, k;ele merge(ele a, ele b) {for(register int i = 0; i < (1 << k); i++) a.f[i] = max(a.f[i], b.f[i]);return a; }void build(int u, int l, int r) {p[u].l = l; p[u].r = r;if(l == r) {for(register int i = 0; i < (1 << k); i++) {p[u].val.f[i] = 0;for(register int j = 0; j < k; j++) {if(i & (1 << j)) p[u].val.f[i] += t[l][j];else p[u].val.f[i] -= t[l][j];}}return;}int mid = (l + r) >> 1;build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r);p[u].val = merge(p[u << 1].val, p[u << 1 | 1].val); }void change(int u, int l) {if(p[u].l == p[u].r) {for(register int i = 0; i < (1 << k); i++) {p[u].val.f[i] = 0;for(register int j = 0; j < k; j++) {if(i & (1 << j)) p[u].val.f[i] += t[l][j];else p[u].val.f[i] -= t[l][j];}}return;}int mid = (p[u].l + p[u].r) >> 1;if(mid >= l) change(u << 1, l); else change(u << 1 | 1, l);p[u].val = merge(p[u << 1].val, p[u << 1 | 1].val); }ele query(int u, int l, int r) {if(p[u].l >= l && p[u].r <= r) return p[u].val;int mid = (p[u].l + p[u].r) >> 1;if(mid >= l && mid + 1 <= r) return merge(query(u << 1, l, r), query(u << 1 | 1, l, r));else if(mid >= l) return query(u << 1, l, r); return query(u << 1 | 1, l, r); }int main() {read(n); read(k);for(register int i = 1; i <= n; i++) {for(register int j = 0; j < k; j++) {read(t[i][j]);}}build(1, 1, n); read(m);while(m--) {int opt; read(opt);if(opt == 1) {int i; read(i); // cout << i << " " << k << endl;for(register int j = 0; j < k; j++) read(t[i][j]);change(1, i);}if(opt == 2) {int l, r; read(l); read(r);ele res = query(1, l, r); int ans = 0;for(register int i = 0; i < (1 << (k - 1)); i++) ans = max(ans, res.f[i] + res.f[(1 << k) - 1 - i]);print(ans, '\n');}}return 0; }
View Code
转载于:https://www.cnblogs.com/The-Pines-of-Star/p/10340954.html
Educational Codeforces Round 56 Editorial相关推荐
- Multidimensional Queries(二进制枚举+线段树+Educational Codeforces Round 56 (Rated for Div. 2))...
题目链接: https://codeforces.com/contest/1093/problem/G 题目: 题意: 在k维空间中有n个点,每次给你两种操作,一种是将某一个点的坐标改为另一个坐标,一 ...
- Codeforces Educational Codeforces Round 56 (Rated for Div. 2) 1093F. Vasya and Array
有一个长度为nnn的的数列,aia_iai的值域只有kkk个元素. 一个数列有一些数字已经填上.现在要求数列连续的数字长度不能超过lll,问所有不同的数列的个数有多少个. 1.考虑所有的数字都没填上 ...
- Educational Codeforces Round 90 (Rated for Div. 2)(A, B, C, D, E)
Educational Codeforces Round 90 (Rated for Div. 2) Donut Shops 思路 分三种情况: a==c/ba == c / ba==c/b这个时候两 ...
- Educational Codeforces Round 24 E. Card Game Again(双指针)
题目链接:Educational Codeforces Round 24 E. Card Game Again 题意: 给你n个数和一个数k. 现在每次可以拿掉前x个数,后y个数,剩下的数的乘积要能被 ...
- [Educational Codeforces Round 16]A. King Moves
[Educational Codeforces Round 16]A. King Moves 试题描述 The only king stands on the standard chess board ...
- Educational Codeforces Round 114 (Rated for Div. 2) (A ~ F)全题解
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Educational Codeforces Round 114 (Rated for Div. 2) ...
- Educational Codeforces Round 106 (Rated for Div. 2)(A ~ E)题解(每日训练 Day.16 )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 Educational Codeforces Round 106 (Rated for Div. ...
- Educational Codeforces Round 32
http://codeforces.com/contest/888 A Local Extrema[水] [题意]:计算极值点个数 [分析]:除了第一个最后一个外,遇到极值点ans++,包括极大和极小 ...
- Educational Codeforces Round 37 (Rated for Div. 2) 1
Educational Codeforces Round 37 (Rated for Div. 2) A.Water The Garden 题意:Max想给花园浇水.花园可被视为长度为n的花园床,花园 ...
最新文章
- About LOCAL_PRIVATE_PLATFORM_APIS in Android.mk
- Qt之自定义界面(窗体缩放)
- Dubbo 跨语言调用神兽:dubbo-go-pixiu
- 10个Github热门Python库,非常实用!
- Spring Boot中防表单重复提交以及拦截器登录检测
- Python 标准库 —— queue、heapq与PriorityQueue
- php获取图片所有颜色代码,php 获取一张图片所有点的颜色值
- 自定义属性-模态框的改进
- 网页转圈打不开服务器,打不开网页怎么回事
- 韩顺平python教程视频_尚硅谷_韩顺平_Linux_2018Linux基础入门教程全集
- Python实现股票查询
- “逃犯克星”张学友演唱会完成八杀,幕后功臣竟然是它
- MOVICS系列教程(二) COMP Module
- 《网络安全》课程论文
- 2022美赛F题题目及思路--人人为我,我(空间)为人人
- 行为识别论文笔记|TSN|Temporal Segment Networks: Towards Good Practices for Deep Action Recognition
- 2020年最新数据标注公司及平台排名
- 计算机里的打印机从哪找,电脑打印机在哪里找出来
- 招银网络科技终面编程题
- 不错的todo建议:应该往todo-list添加什么内容
热门文章
- 解决Maven项目pom.xml文件报xxx\target\classes\META-INF\MANIFEST.MF (系统找不到指定的路径。)问题...
- 位运算及在java中的应用整理
- [Silverlight动画]转向行为 - 转向机车
- 2010版CCNP教材一览【图文】
- 在Red Hat Linux中自动运行程序
- find 和 findindes
- 第九次会议(5.14)
- 为什么软件开发,人多,事少,还会工作量大?
- 自动化运维工具Ansible详细部署
- Host 'XXX' is not allowed to connect to this MySQL server 解决方案/如何开启MySQL的远程帐号...