Codeforces Round #442 (Div. 2) 解题报告
来源:互联网 发布:网络继续教育学院 编辑:程序博客网 时间:2024/05/20 14:40
A.Alex and broken contest
签到题,题目看清
题意懒得说了
#include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#include<set>#include<map>#include<cstring>#define For(i,j,k) for(ll i=j;i<=k;++i)#define Dow(i,j,k) for(ll i=k;i>=j;--i)#define maxm 10011#define maxn 511#define pb push_back#define ll long longusing namespace std;inline ll read(){ ll t=0,f=1;char c=getchar(); while(c<'0'||c>'9') {c=getchar();} while(c<='9'&&c>='0') t=t*10+c-48,c=getchar(); return t*f;}char s[30001];int flag1;int main(){ scanf("%s",s+1); int len=strlen(s+1); For(i,1,len-5) if(s[i]=='N'&&s[i+1]=='i'&&s[i+2]=='k'&&s[i+3]=='i'&&s[i+4]=='t'&&s[i+5]=='a') flag1++; For(i,1,len-3) if(s[i]=='O'&&s[i+1]=='l'&&s[i+2]=='y'&&s[i+3]=='a') flag1++; For(i,1,len-4) if(s[i]=='D'&&s[i+1]=='a'&&s[i+2]=='n'&&s[i+3]=='i'&&s[i+4]=='l') flag1++; For(i,1,len-4) if(s[i]=='S'&&s[i+1]=='l'&&s[i+2]=='a'&&s[i+3]=='v'&&s[i+4]=='a') flag1++; For(i,1,len-2) if(s[i]=='A'&&s[i+1]=='n'&&s[i+2]=='n') flag1++; if(flag1==1) puts("YES");else puts("NO");}
B.Nikita and string
题意:给你一个字符串删掉若干个字母后,让字符串形如aa..a bb..bbb a..aa
。。不知道n^2贪心哪里gg了,反正翻在这了
本来怕DP打错。。然而贪心gg后回去打DP两分钟过了。。stm
记录三段情况到i这个位置的最大合法长度就可以了
1、aaa..aaa
2、aa…aa bb..b
3、a..a b..b a..a
大力转移即可
#include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#include<set>#include<map>#include<cstring>#define For(i,j,k) for(ll i=j;i<=k;++i)#define Dow(i,j,k) for(ll i=k;i>=j;--i)#define maxm 10011#define maxn 511#define pb push_back#define ll long longusing namespace std;inline ll read(){ ll t=0,f=1;char c=getchar(); while(c<'0'||c>'9') {c=getchar();} while(c<='9'&&c>='0') t=t*10+c-48,c=getchar(); return t*f;}char s[20001];int f[20001][4];int main(){ scanf("%s",s+1); int len=strlen(s+1); For(i,1,len) { f[i][0]=f[i-1][0]+(s[i]=='a'); f[i][1]=max(f[i-1][0],f[i-1][1])+(s[i]=='b'); f[i][2]=max(max(f[i-1][0],f[i-1][1]),f[i-1][2])+(s[i]=='a'); } printf("%d\n",max(f[len][0],max(f[len][1],f[len][2])));}
C.Slava and tanks
题意:一个1*n的矩阵中,每个格子上有一个htr,你可以在某个格子上泼水,那么这个格子上的htr就会受到一次伤害并向左或向右移动一格,受到两次伤害的htr会死亡,问最小次数内的泼死所有htr的方案数
思维题,全场最短
很显然,一个奇数位置上的htr受到伤害,他就会跑到偶数点上,反之亦然
那么如果我们先把奇数上泼一遍,再把偶数泼一遍,那么所有原本在奇数点上的htr都死了,所有偶数上的htr都会受到一次伤害并且跑到奇数点。这样的话,再泼一次奇数点即可。
我们发现这样不是最优的,因为奇数点的个数>=偶数点,但是奇数点被泼了两边
所以先泼偶数,再泼奇数,再泼偶数
#include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#include<set>#include<map>#include<cstring>#define For(i,j,k) for(ll i=j;i<=k;++i)#define Dow(i,j,k) for(ll i=k;i>=j;--i)#define maxm 10011#define maxn 511#define pb push_back#define ll long longusing namespace std;inline ll read(){ ll t=0,f=1;char c=getchar(); while(c<'0'||c>'9') {c=getchar();} while(c<='9'&&c>='0') t=t*10+c-48,c=getchar(); return t*f;}int n;int main(){ n=read(); printf("%d\n",n/2+n/2+(n+1)/2); for(int i=2;i<=n;i+=2) printf("%d ",i); for(int i=1;i<=n;i+=2) printf("%d ",i); for(int i=2;i<=n;i+=2) printf("%d ",i);}
D.Olya and Energy Drinks
题意:给一张n*m的图,图上有障碍,一个人要从起始点走到终点,每一步可以朝一个方向走1~k格,求最小步数
BFS。。
#include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#include<set>#include<map>#include<cstring>#define For(i,j,k) for(ll i=j;i<=k;++i)#define Dow(i,j,k) for(ll i=k;i>=j;--i)#define maxm 10011#define maxn 511#define pb push_back#define ll long longusing namespace std;inline ll read(){ ll t=0,f=1;char c=getchar(); while(c<'0'||c>'9') {c=getchar();} while(c<='9'&&c>='0') t=t*10+c-48,c=getchar(); return t*f;}int qx[10000001],qy[10000001],qv[10000001];bool vis[2001][1001][5],no[2001][2001];int n,m,k,ex,ey,sx,sy;int dx[]={0,1,0,-1,0};int dy[]={0,0,1,0,-1};inline void bfs(){ qx[1]=sx;qy[1]=sy;qv[1]=0; int l=1,r=1; For(i,1,4) vis[sx][sy][i]=1; while(l<=r) { int tx=qx[l],ty=qy[l]; if(tx==ex&&ty==ey) { printf("%d",qv[l]); exit(0); } For(dir,1,4) { For(dis,1,k) { int nx=tx+dis*dx[dir],ny=ty+dis*dy[dir]; if(nx<1||ny<1||nx>n||ny>m) break; if(no[nx][ny]) break; if(vis[nx][ny][dir]) break; qv[++r]=qv[l]+1;qx[r]=nx;qy[r]=ny; vis[nx][ny][dir]=1; } } ++l; }}char s[2001];int main(){ n=read();m=read();k=read(); For(i,1,n) { scanf("%s",s+1); For(j,1,m) if(s[j]=='#') no[i][j]=1; } sx=read();sy=read();ex=read();ey=read(); bfs(); puts("-1");}
E.Danil and a Part-time Job
题意:给定一颗树,树上的节点有权值0或1,有两个操作
1、求某个节点为根的子树权值和
2、对某个节点为根的子树中的所有节点的权值取反(xor 1)
时间戳+线段树
。。
模板题
#include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#include<set>#include<map>#include<cstring>#define For(i,j,k) for(ll i=j;i<=k;++i)#define Dow(i,j,k) for(ll i=k;i>=j;--i)#define maxm 10011#define maxn 511#define pb push_back#define ll long longusing namespace std;inline ll read(){ ll t=0,f=1;char c=getchar(); while(c<'0'||c>'9') {c=getchar();} while(c<='9'&&c>='0') t=t*10+c-48,c=getchar(); return t*f;}int poi[400001],nxt[400001],f[400001],cnt,n,m;char opt[10];struct tree{int v,sz;} tr[1000001];int tag[1000001];int in[400001],out[400001],tim,on[400001],to[400001];inline void add(int x,int y){poi[++cnt]=y;nxt[cnt]=f[x];f[x]=cnt;}inline void dfs(int x,int fa){ in[x]=++tim;to[tim]=x; for(int i=f[x];i;i=nxt[i]) { if(poi[i]==fa) continue; dfs(poi[i],x); } out[x]=tim;}inline void up(int x){ tr[x].v=tr[x<<1|1].v+tr[x<<1].v; tr[x].sz=tr[x<<1|1].sz+tr[x<<1].sz;}inline void build(int x,int l,int r){ if(l==r) {tr[x].v=on[to[l]];tr[x].sz=1;return;} int mid=l+r>>1; build(x<<1,l,mid);build(x<<1|1,mid+1,r); up(x);}inline void push(int x){ if(tag[x]) { tag[x<<1]^=1;tag[x<<1|1]^=1; tr[x<<1].v=tr[x<<1].sz-tr[x<<1].v;tr[x<<1|1].v=tr[x<<1|1].sz-tr[x<<1|1].v; tag[x]=0; }}inline int ask(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr) return tr[x].v; int mid=l+r>>1; push(x); int sum=0; if(ql<=mid) sum+=ask(x<<1,l,mid,ql,qr); if(qr >mid) sum+=ask(x<<1|1,mid+1,r,ql,qr); up(x); return sum; }inline void change(int x,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr) { tr[x].v=tr[x].sz-tr[x].v; tag[x]^=1; return; } int mid=l+r>>1; push(x); if(ql<=mid) change(x<<1,l,mid,ql,qr); if(qr >mid) change(x<<1|1,mid+1,r,ql,qr); up(x);}int main(){ n=read(); For(i,1,n-1) add(read(),i+1); For(i,1,n) on[i]=read(); dfs(1,1); build(1,1,n); m=read(); For(i,1,m) { scanf("%s",opt+1); if(opt[1]=='g') { int x=read(); printf("%d\n",ask(1,1,n,in[x],out[x])); } else { int x=read(); change(1,1,n,in[x],out[x]); } }}
F.Ann and Books
我大莫队名声远扬!
题意:给定一个序列,有q个询问(L,R),每个询问求L~R之间和=k的子段数量
对原序列差分,得到一个新的序列s[i]
可以把问题转化为
有多少个 sj=si+k (L-1<=i<=j<=R)
这里要注意,是到L-1,因为这个是差分数组
所以我们考虑对我们有用的权值其实就是所有的s[i],s[i]+k,s[i]-k
于是我们把这些数提出来,离散一波
接下来直接上莫队就行了
修改可以做到O(1)
记录v[i]表示i这个数字在当前区间内出现的次数
还是要注意一下L-1这个东西。。因为L-1不在我们的当前区间内,需要最后加上
复杂度O(n^1.5)
#include<iostream>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>#include<set>#include<map>#include<cstring>#define For(i,j,k) for(ll i=j;i<=k;++i)#define Dow(i,j,k) for(ll i=k;i>=j;--i)#define maxm 10011#define maxn 511#define pb push_back#define ll long longusing namespace std;inline ll read(){ ll t=0,f=1;char c=getchar(); while(c<'0'||c>'9') {c=getchar();} while(c<='9'&&c>='0') t=t*10+c-48,c=getchar(); return t*f;}map<ll,int> mp;int v[400001],lst[400001],nxt[400001],t[400001],n,k,m;ll ans;struct node{int L,R,bl,br,n,num;ll ans;} que[400001];inline bool cmp(node x,node y){return x.bl!=y.bl?x.bl<y.bl:x.br<y.br;}ll s[400001];inline void change(int x,int del,int LR){ if(del==-1) v[s[x]]--; if(LR==1) ans+=v[lst[x]]*del; else ans+=v[nxt[x]]*del; if(del==1) v[s[x]]++;}inline void MO(){ int l=1,r=0; For(i,1,m) { while(r<que[i].R){r++;change(r,1,1);} while(r>que[i].R){change(r,-1,1);r--;} while(l<que[i].L){change(l,-1,2);l++;} while(l>que[i].L){l--;change(l,1,2);} que[i].ans=ans+v[nxt[l-1]]; }}ll q[500001],top,tot;inline bool cmp1(node x,node y){return x.num<y.num;}int main(){ n=read();k=read(); For(i,1,n) t[i]=read(); For(i,1,n) { ll x=read(); s[i]=s[i-1]+x*(t[i]==1?1:-1); } For(i,1,n) q[++top]=s[i],q[++top]=s[i]+k,q[++top]=s[i]-k; q[++top]=0;q[++top]=k; sort(q+1,q+top+1); For(i,1,top) if(!mp[q[i]]) mp[q[i]]=++tot; nxt[0]=mp[k]; For(i,1,n) { lst[i]=mp[s[i]-k]; nxt[i]=mp[s[i]+k]; s[i]=mp[s[i]]; } m=read(); int block=sqrt(n); For(i,1,m) que[i].L=read(),que[i].R=read(),que[i].num=i; For(i,1,m) que[i].bl=que[i].L/block,que[i].br=que[i].R/block; sort(que+1,que+m+1,cmp); MO(); sort(que+1,que+m+1,cmp1); For(i,1,m) printf("%I64d\n",que[i].ans);}
- Codeforces Round #442 (Div. 2) 解题报告
- Codeforces Round #149 (Div. 2)解题报告
- Codeforces Round #180 (Div. 2) 解题报告
- Codeforces Round #190 (Div. 2) 解题报告
- Codeforces Round #191 (Div. 2) 解题报告
- Codeforces Round #189 (Div. 2) 解题报告
- Codeforces Round #142 (Div. 2) 解题报告
- Codeforces Round #229 (Div. 2) 解题报告
- Codeforces Round #241 (Div. 2) 解题报告
- Codeforces Round #262 (Div. 2)解题报告
- Codeforces Round #267 (Div. 2) 解题报告
- Codeforces Round #266 (Div. 2)解题报告
- Codeforces Round #268 (Div. 2) 解题报告
- Codeforces Round #271 (Div. 2) 解题报告
- Codeforces Round #274 (Div. 2) 解题报告
- Codeforces Round #276 (Div. 2) 解题报告
- Codeforces Round #277 (Div. 2) 解题报告
- Codeforces Round #224 (Div. 2)解题报告
- noip题目复习
- 操作系统面试题汇总(持续更新)
- 购物车
- 机器学习入门笔记(十一)----推荐系统
- 北京师范大学第十四届ACM决赛- F Training Plan
- Codeforces Round #442 (Div. 2) 解题报告
- angular利用双向数据绑定改变样式
- java面试题收集
- HttpURLConnection 和GSON解析
- sql语句中的连接字符
- 前端:Import in body of module; reorder to top import/first
- Opencv之获取边缘和画轮廓
- 从键盘输入一个大写字母,转换成小写字母
- 专访姚冬:All-in-One,智能时代下企业需要更快速的变革