您的位置:首页 > 其它

一次毒瘤的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了

好久没有这么低的分数了

洛谷打卡真是有毒

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: