一次毒瘤的NOIP模拟赛
2018-01-24 12:35
232 查看
写在前面
我真的真的好久没有这么sb过了题目描述
由于fzoj有点狗 所以我把题目附上来A题
B题
C题
想说的话
刚看到的时候 这题真是太虎了随便写写就A了
然后我就要自黑一波了 只得了十分也没什么可辩解的
但是全都是RE也是很闹挺
A题思路全过程以及题解
刚看到的时候我就在想 最短路果断Dijkstra+Heap但是这个复杂度有点鬼 果断卡死
然后发现这是一棵树(汗
接着就跑lca(我是倍增选手
跑着跑着发现深度不是距离
就想着把深度赋成距离吧
然后我用距离倍增 真是傻
题解大概都懂
就是找到LCA然后用这两个点到根的距离减去两倍的LCA到根的距离
A题代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define N 200001 #define lowbit(x) x&-x int head ,cnt,n,m,dis ,fa [21],k,vs ; int deep ; struct edge { int to,nxxt,len; }e ; inline void addedge(int u,int v,int len) { cnt++; e[cnt].len=len; e[cnt].to=v; e[cnt].nxxt=head[u]; head[u]=cnt; } inline void superadd(int u,int v,int w) { addedge(u,v,w); addedge(v,u,w); } void dfs(int now,int f) { for(int i=head[now];i;i=e[i].nxxt) { int to=e[i].to; if(to==f) continue; dis[to]=dis[now]+e[i].len; deep[to]=deep[now]+1; fa[to][0]=now; dfs(to,now); } } inline int getLCA(int u,int v) { if(deep[u]<deep[v]) swap(u,v); for(int i=20;i>=0;i--) { if(deep[ fa[u][i] ]>=deep[v]) u=fa[u][i]; if(deep[u]==deep[v]) break; } if(u==v) return u; for(int i=20;i>=0;i--) { if(fa[u][i]!=fa[v][i]) { u=fa[u][i],v=fa[v][i]; } } return fa[u][0]; } int main() { scanf("%d",&n); for(int i=1;i<n;i++) { int begi,endd,val; scanf("%d%d%d",&begi,&endd,&val); superadd(begi,endd,val); } deep[1]=0; dfs(1,0); for(int i=1;i<=20;i++) { for(int j=1;j<=n;j++) { fa[j][i]=fa[fa[j][i-1]][i-1]; } } scanf("%d",&m); for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); printf("%d\n",dis[a]+dis[b]-2*dis[ getLCA(a,b) ]); } }
B题思路全过程以及题解
这题其实我在之前做过类似的然后写了一个Segtree
打lz标记的时候区间加打成区间修改直接gg
其他的神犇们栽在了long long 上面
真是虎
题解
对于树跑一遍dfs序
之后线段树 区间修改 单点查询 区间查询
超休闲的
B题代码
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define N 200005 #define M 400005 #define ls q<<1 #define rs q<<1|1 long long head ,dfn ,id ,n,m,cnt,size ,val ,tot; struct edge { long long to,nxxt; }e[M]; struct treenode { long long begi,endd,sum,lz; }tree[N<<2]; inline void addedge(long long u,long long v) { cnt++; e[cnt].to=v; e[cnt].nxxt=head[u]; head[u]=cnt; } inline void superadd(long long u,long long v) { addedge(u,v); addedge(v,u); } void dfs(long long u,long long fa) { tot++; dfn[cnt]=u; id[u]=tot; size[u]=1; for(long long i=head[u];i;i=e[i].nxxt) { long long to=e[i].to; if(to==fa) continue; dfs(to,u); size[u]+=size[to]; } } inline void buildtree(long long q,long long l,long long r) { tree[q].begi=l,tree[q].endd=r; if(l==r) { tree[q].sum=0; return; } long long mid=(l+r)>>1; buildtree(ls,l,mid); buildtree(rs,mid+1,r); tree[q].sum=tree[ls].sum+tree[rs].sum; } inline void pushdown(long long q) { if(tree[q].lz==0) return; tree[ls].lz+=tree[q].lz; tree[rs].lz+=tree[q].lz; tree[ls].sum+=(tree[ls].endd-tree[ls].begi+1)*tree[q].lz; tree[rs].sum+=(tree[rs].endd-tree[rs].begi+1)*tree[q].lz; tree[q].lz=0; } inline void modify(long long q,long long l,long long r,long long x) { if(tree[q].begi>=l&&tree[q].endd<=r) { tree[q].sum+=(tree[q].endd-tree[q].begi+1)*x; tree[q].lz+=x; return; } pushdown(q); long long mid=(tree[q].begi+tree[q].endd)>>1; if(mid>=r) modify(ls,l,r,x); else if(mid<l) modify(rs,l,r,x); else { modify(ls,l,mid,x); modify(rs,mid+1,r,x); } tree[q].sum=tree[ls].sum+tree[rs].sum; } inline long long query(long long q,long long l,long long r) { if(tree[q].begi==l&&tree[q].endd==r) return tree[q].sum; long long mid=(tree[q].begi+tree[q].endd)>>1; pushdown(q); if(mid>=r) return query(ls,l,r); else if(mid<l) return query(rs,l,r); else return query(ls,l,mid)+query(rs,mid+1,r); } int main() { char opt[10]; scanf("%lld",&n); for(long long i=1;i<n;i++) { long long begi,endd; scanf("%lld%lld",&begi,&endd); superadd(begi,endd); } dfs(1,0); buildtree(1,1,n); scanf("%lld",&m); for(long long i=1;i<=m;i++) { scanf("%s",opt); if(opt[0]=='g') { long long x,y; scanf("%lld%lld",&x,&y); modify(1,id[x],id[x]+size[x]-1,y); } else if(opt[0]=='s') { long long x; scanf("%lld",&x); printf("%lld\n",query(1,id[x],id[x])); } else { long long x; scanf("%lld",&x); printf("%lld\n",query(1,id[x],id[x]+size[x]-1)); } } }
C题思路全过程以及题解
这题是平衡树裸题就是插入的时候每个数都有自己的个数
就是需要在插入的时候加上一个权值
最sb的地方就是删除操作可能删除没有的数?!
你tm逗我呢!?
于是乎我们只能用一个hash数组存储一下当前有没有这个数
有几个
然后平衡树就好
我想着splay慢 就第一次尝试了treap
效果还是不错的
就是手贱把fread和scanf一起用了
导致直接RE一分没有
题解
平衡树维护插入 删除 查询第k小
注意判断删除的时候数列里面有没有
C题代码
#include<iostream> #include<iomanip> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> using namespace std; inline int read(){ char ch=getchar();int sum=0,w=1; while(!(ch>='0'&&ch<='9')) {if(ch=='-') w=-1;ch=getchar();} while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=getchar(); return sum*w; } struct data { int l,r,v,w,sz,rnd; }tr[500010]; int n,rt,sze,m; char opt[10]; inline void update(int k) { tr[k].sz=tr[tr[k].l].sz+tr[tr[k].r].sz+tr[k].w; } inline void lturn(int &k) { int t=tr[k].r; tr[k].r=tr[t].l; tr[t].l=k; tr[t].sz=tr[k].sz; update(k); k=t; } inline void rturn(int &k) { int t=tr[k].l; tr[k].l=tr[t].r; tr[t].r=k; tr[t].sz=tr[k].sz; update(k); k=t; } inline void insert(int &k,int x,int y) { if(k==0) { sze++; k=sze; tr[k].sz=tr[k].w=y; tr[k].v=x; tr[k].rnd=rand(); return; } tr[k].sz+=y; if(tr[k].v==x)tr[k].w+=y; else if(x<=tr[k].v) { insert(tr[k].l,x,y); if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k); } else { insert(tr[k].r,x,y); if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k); } } inline void del(int &k,int x) { if(k==0)return; if(tr[k].v==x) { if(tr[k].w>1) { tr[k].w--; tr[k].sz--; return; } if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r; else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd) { rturn(k); del(k,x); } else { lturn(k); del(k,x); } } else if(tr[k].v>x) { tr[k].sz--; del(tr[k].l,x); } else { tr[k].sz--; del(tr[k].r,x); } } inline int que_num(int k,int x) { if(k==0)return 0; if(x<=tr[tr[k].l].sz) { return que_num(tr[k].l,x); } else if(x>tr[tr[k].l].sz+tr[k].w) { return que_num(tr[k].r,x-tr[tr[k].l].sz-tr[k].w); } else return tr[k].v; } int fff=100000,haxx[500010]; int main() { int rbound,lbound; lbound=read(),rbound=read(); for(int i=lbound;i<=rbound;i++) { int num; num=read(); insert(rt,i,num); haxx[i+fff]=num; } n=read(); for(int i=1;i<=n;i++) { scanf("%s",opt); if(opt[0]=='q') { m=read(); update(rt); printf("%d",que_num(rt,m)); putchar(10); } else if(opt[0]=='a') { m=read(); insert(rt,m,1); haxx[fff+m]++; } else {m=read();if(haxx[fff+m]) {del(rt,m);haxx[fff+m]--;}} } }
写在最后
今天真是太sb了好久没有这么低的分数了
洛谷打卡真是有毒
相关文章推荐
- 一次愚蠢的NOIP模拟赛
- 20160728noip模拟赛zld
- 2017.08.05【NOIP提高组】模拟赛B组小结
- 2016.12.03【初中部 NOIP提高C组】模拟赛
- 2017.08.15【NOIP 普及组】模拟赛C组 猴子拆房
- 【总结】20151017重庆市NOIP模拟赛
- 【动态规划】【图论】[NOIP模拟赛]独立集
- [noip模拟赛]敲砖块(dp)
- 【重庆市NOIP模拟赛】业务
- JZOJ(中山纪中)2018.01.21【NOIP普及组】模拟赛D组(第三题)
- JZOJ(中山纪中) 2018.01.26【NOIP普及组】模拟赛D组 第四题
- 2018.01.31【NOIP普及组】模拟赛D组
- JZOJ(中山纪中) 2018.01.30【NOIP普及组】模拟赛D组 第二题
- 计蒜客 2017 NOIP 提高组模拟赛(一)Day1
- 2017-9-13 NOIP模拟赛[xxy]
- 2017.3.18【NOIP提高组】模拟赛B组 T1:人类基因组
- noip模拟赛 天天寄快递
- 2017.03.18【NOIP 普及组】模拟赛C组 剪草 题解
- 2016.10.05【初中部 NOIP普及组 】模拟赛总结
- noip模拟赛(10.4) 序列(sequence)