2017/7/15 离线赛
来源:互联网 发布:java程序开发步骤 编辑:程序博客网 时间:2024/05/01 13:32
第一题 NOIP2016普及组复赛T3 海港
题目很长,但是意思很明确。因为船到达的时间是递增的,所以直接按数据顺序模拟过来就好。我的做法是,按1~n的顺序枚举过来,把一艘艘船塞进队列,再把队列前面时间太早的船删去,即对于第
struct node{ int t,k,L,R;}s[M];int n;int cnt[M],A[3*M];int main(){ Rd(n); int tmp=0; for(int i=1;i<=n;i++){ Rd(s[i].t);Rd(s[i].k); s[i].L=tmp+1;s[i].R=tmp+s[i].k; for(int j=s[i].L;j<=s[i].R;j++)Rd(A[j]); tmp=s[i].R; } int res=0; queue<node>que; for(int i=1;i<=n;i++){ while(!que.empty()&&que.front().t<=s[i].t-86400){ node q=que.front();que.pop(); for(int j=q.L;j<=q.R;j++){ if(cnt[A[j]]==1)res--; cnt[A[j]]--; } } for(int j=s[i].L;j<=s[i].R;j++){ if(!cnt[A[j]])res++; cnt[A[j]]++; } que.push(s[i]); Pt(res); putchar('\n'); } return 0;}
第二题 NOIP2016普及组复赛T4 魔法阵
刚看完这道题的时候,我想到其实本题只有
struct node{ int x,y; bool operator <(const node &tmp)const{ return x>tmp.x; }};int BIT[2][N][N];priority_queue<node>que[N];int n,m;int A[M];int tmp[M];//有哪些数字,最多1~15000int tt[N];int cnt[N][4];//数字i在各个位置的次数void add(int k,int d,int x,int a){ int i=x; while(i<=n){ BIT[k][d][i]+=a; i+=(i&-i); }}int sum(int k,int d,int x){ int i=x,res=0; while(i>0){ res+=BIT[k][d][i]; i-=(i&-i); } return res;}int main(){ Rd(n);Rd(m); for(int i=1;i<=m;i++){ Rd(A[i]); tt[A[i]]++; tmp[i]=A[i]; } sort(tmp+1,tmp+m+1); int k=unique(tmp+1,tmp+m+1)-tmp;//1~k-1; for(int i=1;i<k;i++) for(int j=i+1;j<k;j++) que[tmp[j]-tmp[i]].push((node){tmp[i],tmp[j]}); for(int i=1;i<=n;i++) while(!que[i].empty()){ node q=que[i].top();que[i].pop(); int x=q.x,y=q.y; add(0,i,n-x+1,tt[x]*tt[y]); add(1,i,y,tt[x]*tt[y]); } for(int i=1;i<k;i++) for(int j=i+1;j<k;j++){ int t=tmp[j]-tmp[i]; if(t%2)continue; int ttt=sum(0,t>>1,n-(tmp[j]+3*t+1)+1); cnt[tmp[i]][0]+=ttt*tt[tmp[j]]; cnt[tmp[j]][1]+=ttt*tt[tmp[i]]; } for(int i=1;i<k;i++) for(int j=1;j<k;j++){ int t=tmp[j]-tmp[i]; if((t<<1)>=N)continue; int ttt=sum(1,t<<1,tmp[i]-3*(t<<1)-1); cnt[tmp[i]][2]+=ttt*tt[tmp[j]]; cnt[tmp[j]][3]+=ttt*tt[tmp[i]]; } for(int i=1;i<=m;i++){ Pt(cnt[A[i]][0]); for(int j=1;j<4;j++){ putchar(' '); Pt(cnt[A[i]][j]); } putchar('\n'); } return 0;}
下面来说一下
int n,m;int A[M],cnt[N],res[N][4];int main(){ Rd(n);Rd(m); for(int i=1;i<=m;i++){ Rd(A[i]); cnt[A[i]]++; } for(int k=1;k<=n;k++){ int sum=0; for(int i=n-9*k-1;i>=1;i--){ sum+=cnt[i+(8*k+1)]*cnt[i+(9*k+1)]; res[i][0]+=sum*cnt[i+2*k]; res[i+2*k][1]+=sum*cnt[i]; } sum=0; for(int i=2+9*k;i<=n;i++){ sum+=cnt[i-(9*k+1)]*cnt[i-(7*k+1)]; res[i-k][2]+=sum*cnt[i]; res[i][3]+=sum*cnt[i-k]; } } for(int i=1;i<=m;i++){ Pt(res[A[i]][0]); for(int j=1;j<4;j++){ putchar(' '); Pt(res[A[i]][j]); } putchar('\n'); } return 0;}
第三题 AHOI2005 航线规划
我一开始先敲了个暴力,就是枚举每条边,再跑一次dfs,这样只能拿30分。假如没有删边操作的话,就可以敲个Tarjan了,求出桥边,再预处理出每个点到根的路径中有多少条桥边就OK了。既然有删边操作,我们就要思考思考了,倘若我们顺着题目的意思将边一条一条删去,那么有可能就删到之前建立树边了,这样我们又要重新建一棵树,假如每次删的边都是树边,那么复杂度就是
struct edge{ int v,nxt;}e[M<<1];int n,m,q,cnt,tim;int head[N],dep[N],sz[N],pa[N],fa[N][Max],dfn[N];int op[Q],A[Q],B[Q],BIT[N],ans[Q];set<int>no[N];void add_edge(int u,int v){ e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;}void Init(){ for(int k=0;k<Max;k++) for(int i=1;i<=n;i++) if(~fa[i][k])fa[i][k+1]=fa[fa[i][k]][k];}void add(int x,int a){ int i=x; while(i<=n){ BIT[i]+=a; i+=i&-i; }}int sum(int x){ int res=0,i=x; while(i){ res+=BIT[i]; i-=i&-i; } return res;}int getfa(int v){ if(pa[v]==v)return v; return pa[v]=getfa(pa[v]);}void merge(int x,int y){ x=getfa(x); y=getfa(y); while(x!=y){ if(dep[x]<dep[y])swap(x,y); add(dfn[x],-1); add(dfn[x]+sz[x],1); pa[x]=fa[x][0]; x=getfa(x); }}void dfs(int x,int t){ dfn[x]=++tim; sz[x]=1; if(~t)dep[x]=dep[t]+1; else dep[x]=0; fa[x][0]=t; for(int i=head[x];~i;i=e[i].nxt){ int v=e[i].v; if(dfn[v]||no[x].count(v))continue; dfs(v,x); sz[x]+=sz[v]; } add(dfn[x],1); add(dfn[x]+sz[x],-1);}void dfs1(int x,int t){ for(int i=head[x];~i;i=e[i].nxt){ int v=e[i].v; if(v==t||no[x].count(v))continue; if(fa[v][0]==x)dfs1(v,x); else merge(x,v); }}int LCA(int u,int v){ if(dep[u]<dep[v])swap(u,v); int c=dep[u]-dep[v]; for(int k=0;k<Max;k++) if(c&(1<<k))u=fa[u][k]; if(u==v)return u; for(int k=Max-1;k>=0;k--) if(fa[u][k]!=fa[v][k]){ u=fa[u][k]; v=fa[v][k]; } return fa[u][0];}int main(){ memset(fa,-1,sizeof(fa)); memset(head,-1,sizeof(head)); int a,b; Rd(n);Rd(m);Rd(q); for(int i=1;i<=m;i++){ Rd(a);Rd(b); add_edge(a,b); add_edge(b,a); } for(int i=1;i<=q;i++){ Rd(op[i]);Rd(A[i]);Rd(B[i]); if(!op[i]){ no[A[i]].insert(B[i]); no[B[i]].insert(A[i]); } } for(int i=1;i<=n;i++)pa[i]=i; dfs(1,-1); Init(); dfs1(1,-1); for(int i=q;i>=1;i--){ int a=A[i],b=B[i]; if(op[i]){ int lca=LCA(a,b); ans[i]=sum(dfn[a])+sum(dfn[b])-2*sum(dfn[lca]); }else merge(a,b); } for(int i=1;i<=q;i++) if(op[i])Pt(ans[i]),putchar('\n'); return 0;}
总之呢,还需努力,还有好多算法没学呢。_(:зゝ∠)_
- 2017/7/15 离线赛
- 2017/9/15 离线赛
- 2017-10-15离线赛
- 2017/7/24 离线赛
- 2017/7/27 离线赛
- 2017/8/7 离线赛
- 2017-10-15离线赛总结
- 2017/7/29 离线赛 总结
- 2017-10-7离线赛题解
- 2017-10-7离线赛总结
- 2017-11-7离线赛总结
- 2017.10.15离线赛总结
- 2017/8/5 离线赛
- 2017/8/9 离线赛
- 2017/8/11 离线赛
- 2017/8/14 离线赛
- 2017/8/19 离线赛
- 2017/8/20 离线赛
- 【C/C++】sizeof问题总结
- C++枚举类型
- 刷题记录-codevs2144 砝码称重 2
- iOS中UIControl详解
- bzoj 4756: [Usaco2017 Jan]Promotion Counting dsu on tree+树状数组
- 2017/7/15 离线赛
- Python 下socket编程地址被占用问题:Address already in use
- Python学习难点和易错点
- python3.5+pyqt5+anaconda+mysql-connector 环境搭建
- MySQL学习记录
- Java学习笔记 05
- mysql基础
- 剑指offer:(40)知识迁移 :数组中只出现一次的数字
- 马士兵JAVA自学之路