博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
COJ968 WZJ的数据结构(负三十二)
阅读量:5236 次
发布时间:2019-06-14

本文共 2841 字,大约阅读时间需要 9 分钟。

 

WZJ的数据结构(负三十二)
难度级别:D; 运行时间限制:5000ms; 运行空间限制:262144KB; 代码长度限制:2000000B
试题描述

给你一棵N个点的无根树,边上均有权值,每个点上有一盏灯,初始均亮着。请你设计一个数据结构,回答M次操作。

1 x:将节点x上的灯拉一次,即亮变灭,灭变亮。

2 x k:询问当前所有亮灯的节点中距离x第k小的距离(注意如果x亮着也算入)。

输入
第一行为一个正整数N。
第二行到第N行每行三个正整数ui,vi,wi。表示一条树边从ui到vi,距离为wi。
第N+1行为一个正整数M。
最后M行每行三个或两个正整数,格式见题面。
输出
对于每个询问操作,输出答案。
输入示例
10
1 2 2
1 3 1
1 4 3
1 5 2
4 6 2
4 7 1
6 8 1
7 9 2
7 10 1
5
2 1 4
1 5
2 1 4
2 1 9
2 1 1
输出示例
2
3
6
0
其他说明
1<=N,M<=50000
1<=x,ui,vi<=N,1<=v,wi<=1000

动态树分治的码农题啦。

对于每个节点用两棵Treap分别维护子树中亮灯的节点到其距离与子树中亮灯的节点到其父亲距离。

修改直接insert/remove。

询问先二分答案,转化成判定问题,这很容易在Treap上做。

修改O(log^2n),询问O(log^3n),常数还挺小的。

说起来还真是简单呢!写了2h+。

#include
#include
#include
#include
#include
#define rep(i,s,t) for(int i=s;i<=t;i++)#define dwn(i,s,t) for(int i=s;i>=t;i--)#define ren for(int i=first[x];i;i=next[i])using namespace std;inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;}const int maxn=100010;struct Node { Node* ch[2]; int r,s,v; void maintain() {s=ch[0]->s+ch[1]->s+1;}}nodes[maxn*20],*null=&nodes[0];int ToT;queue
Q;Node* newnode(int v) { Node* o; if(Q.empty()) o=&nodes[++ToT]; else o=Q.front(),Q.pop(); o->v=v;o->s=1;o->ch[0]=o->ch[1]=null;o->r=rand(); return o;}void del(Node* &o) {Q.push(o);o=null;}void rotate(Node* &o,int d) { Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o; o->maintain();k->maintain();o=k;}void insert(Node* &o,int v) { if(o==null) o=newnode(v); else { int d=v>o->v;insert(o->ch[d],v); if(o->ch[d]->r>o->r) rotate(o,d^1); else o->maintain(); }}void remove(Node* &o,int v) { if(o->v==v) { Node* k=o; if(o->ch[0]==null) o=o->ch[1],del(k); else if(o->ch[1]==null) o=o->ch[0],del(k); else { int d=o->ch[0]->r>o->ch[1]->r; rotate(o,d);remove(o->ch[d],v); } } else remove(o->ch[v>o->v],v); if(o!=null) o->maintain();}int query(Node* &o,int v) { if(o==null) return 0; if(v>o->v) return query(o->ch[1],v)+o->ch[0]->s+1; return query(o->ch[0],v);}int n,m,first[maxn],next[maxn<<1],to[maxn<<1],dis[maxn<<1],e;void AddEdge(int w,int v,int u) { dis[++e]=w;to[e]=v;next[e]=first[u];first[u]=e; dis[++e]=w;to[e]=u;next[e]=first[v];first[v]=e;}int dep[maxn],mn[maxn<<1][20],Log[maxn<<1],cnt,pos[maxn];void dfs(int x,int fa) { mn[++cnt][0]=dep[x];pos[x]=cnt; ren if(to[i]!=fa) { dep[to[i]]=dep[x]+dis[i]; dfs(to[i],x); mn[++cnt][0]=dep[x]; }}void pre() { Log[0]=-1; rep(i,1,cnt) Log[i]=Log[i>>1]+1; for(int j=1;(1<
<=cnt;j++) for(int i=1;i+(1<
<=cnt;i++) mn[i][j]=min(mn[i][j-1],mn[i+(1<
y) swap(x,y); int k=Log[y-x+1]; return ans-2*min(mn[x][k],mn[y-(1<
>1)>=k) r=mid; else l=mid+1; printf("%d\n",l); } } return 0;}
View Code

 

转载于:https://www.cnblogs.com/wzj-is-a-juruo/p/4699480.html

你可能感兴趣的文章
来自XP的道别信
查看>>
CRM系统的两个核心
查看>>
js如何获取response header信息
查看>>
python_文件的打开和关闭
查看>>
mysql archive存储引擎导入数据报duplicate key
查看>>
ADO.NET介绍
查看>>
iOS: 数据持久化方案
查看>>
Neo4j学习笔记
查看>>
【C#】【Thread】Monitor和Lock
查看>>
UVALive - 3635 - Pie(二分)
查看>>
jQuery的中文乱码问题[转]
查看>>
P1631 序列合并
查看>>
Luogu_4886 快递员
查看>>
内存优化文章链接
查看>>
ext4.0 代理 的使用
查看>>
数据检查约束类型和语法
查看>>
AngularJS实战之路由ui-view
查看>>
使用jQuery+huandlebars防止编码注入攻击
查看>>
C#的托管与非托管大难点
查看>>
[转]HTTPS简谈
查看>>