uva1479 - Graph and Queries Treap名次树

Bridge - 判断图是否连通 - 图的遍历 or 并查集搜索 or 强连通算法 You are given an undirected connected graph with N vertices and M edges that does not contain self-loops and double edges. The i-th edge (1≤i≤M) connects Vertex ai and Vertex bi. An edge whose removal disconnec 阅读详情

You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the beginning. You're also given a sequence of operations and you need to process them as requested. Here's a list of the possible operations that you might encounter:


  1. Deletes an edge from the graph.

    The format is [D X], where X is an integer from 1 to M, indicating the ID of the edge that you should delete. It is guaranteed that no edge will be deleted more than once.

  2. Queries the weight of the vertex with K-th maximum value among all vertexes currently connected with vertex X (including X itself).

    The format is [Q X K], where X is an integer from 1 to N, indicating the id of the vertex, and you may assume that K will always fit into a 32-bit signed integer. In case K is illegal, the value for that query will be considered as undefined, and you should return 0 as the answer to that query.

  3. Changes the weight of a vertex.

    The format is [C X V], where X is an integer from 1 to N, and V is an integer within the range [-106, 106].

The operations end with one single character, E, which indicates that the current case has ended. For simplicity, you only need to output one real number - the average answer of all queries.

Input 

There are multiple test cases in the input file. Each case starts with two integers N and M (1$ \le$N$ \le$2 * 104, 0$ \le$M$ \le$6 * 104), the number of vertexes in the graph. The next N lines describes the initial weight of each vertex (- 106$ \le$[weight][i]$ \le$106). The next part of each test case describes the edges in the graph at the beginning. Vertexes are numbered from 1 to N. The last part of each test case describes the operations to be performed on the graph. It is guaranteed that the number of query operations [Q X K] in each case will be in the range [1, 2 * 105], and there will be no more than 2 * 105 operations that change the values of the vertexes [C X V].

There will be a blank line between two successive cases. A case with N = 0, M = 0 indicates the end of the input file and this case should not be processed by your program.

Output 

For each test case, output one real number - the average answer of all queries, in the format as indicated in the sample output. Please note that the result is rounded to six decimal places.


Explanation for samples:

For the first sample:

D 3 - deletes the 3rd edge in the graph (the remaining edges are (1, 2) and (2, 3))

Q 1 2 - finds the vertex with the second largest value among all vertexes connected with 1. The answer is 20.

Q 2 1 - finds the vertex with the largest value among all vertexes connected with 2. The answer is 30.

D 2 - deletes the 2nd edge in the graph (the only edge left after this operation is (1, 2))

Q 3 2 - finds the vertex with the second largest value among all vertexes connected with 3. The answer is 0 (Undefined).

C 1 50 - changes the value of vertex 1 to 50.

Q 1 1 - finds the vertex with the largest value among all vertex connected with 1. The answer is 50.

E - This is the end of the current test case. Four queries have been evaluated, and the answer to this case is (20 + 30 + 0 + 50) / 4 = 25.000.


For the second sample, caution about the vertex with same weight:

Q 1 1 - the answer is 20

Q 1 2 - the answer is 20

Q 1 3 - the answer is 10

Sample Input 

3 3 
10 
20 
30 
1 2 
2 3 
1 3 
D 3 
Q 1 2 
Q 2 1 
D 2 
Q 3 2 
C 1 50
Q 1 1
E

3 3 
10 
20 
20 
1 2 
2 3 
1 3 
Q 1 1 
Q 1 2 
Q 1 3 
E 
0 0

Sample Output 

Case 1: 25.000000 
Case 2: 16.666667

    N个节点M条边的无向图,每个节点都有一个整数权值,有三种操作。

    D X 删除ID为X的边。Q X K,计算与节点X连通的节点中(包括本身)第K大的值。如果不存在为0。C X V,把结点X的权值改为V。输出所有Q指令计算结果的平均值。

    Treap名次树就是排序二叉树多了个rank,这棵树的rank值符合堆的性质,父亲的rank大。这是为了避免二叉树插入顺序的极端情况,每新建结点的时候随机一个rank值,和把所有结点随机排序再插入等价。

    插入的时候先按一般排序二叉树插入,再判断根结点和插入这个结点的子树的根结点的rank,如果不符合堆的性质,就旋转。旋转分为左旋和右旋,左旋是把根变成右结点的左结点,原来右结点的左结点变成原来根的右结点,原来根的右结点变成根。右旋是把根变成左结点的右结点,原来左结点的右结点变成原来根的左结点,原来根的左结点变成根。

    离线处理,把所有操作反过来。最开始把最后剩下的边全加到图里。遇到D操作就相当于把这条边加到图里,遇到C操作就是把V改成X。这样倒着来是因为删边不好删,加边只需要找出两个端点所在的集合合并就行了。注意把结点数少的合并到结点数多的集合中,对于任意结点来说,每次移动到新的树汇中时,该结点所在的树的大小至少加倍,所以任意结点至多被移动logN次,每次移动需要O(logN)的时间,因此总时间复杂度为O(nlog^2n)。

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<set>
#include<map>
#include<stack>
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define MAXNODE 8*MAXN
#define eps 1e-10
using namespace std;
typedef long long LL;

const int MAXN=20010;
const int MAXM=60010;
const int MAXC=500010;

int N,M,K,query_cnt;
LL query_tot;
int pa[MAXN],weight[MAXN],removed[MAXM];
char str[10];

struct Node{
    Node* ch[2];    //左右子树
    int r;          //优先级
    int v;          //值
    int s;          //结点总数

    Node(int v):v(v){
        ch[0]=ch[1]=NULL;
        r=rand();   //随机一个r值
        s=1;
    }
    bool operator < (const Node& rhs) const{
        return r<rhs.r;
    }
    int cmp(int x) const{
        if(x==v) return -1;
        return x<v?0:1;
    }
    void maintain(){
        s=1;
        if(ch[0]!=NULL) s+=ch[0]->s;
        if(ch[1]!=NULL) s+=ch[1]->s;
    }
}* root[MAXN];

struct Edge{
    int from,to;
}edge[MAXM];

struct Command{
    char op;
    int x,k;
}command[MAXC];

//d=0左旋,d=1右旋
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 x){
    if(o==NULL) o=new Node(x);
    else{
        int d=(x<o->v?0:1);
        insert(o->ch[d],x);
        if(o->ch[d]->r>o->r) rotate(o,d^1);
    }
    o->maintain();
}

void remove(Node* &o,int x){
    int d=o->cmp(x);
    if(d==-1){
        Node* u=o;
        if(o->ch[0]!=NULL&&o->ch[1]!=NULL){
            int d2=(o->ch[0]->r>o->ch[1]->r?1:0);
            rotate(o,d2);
            remove(o->ch[d2],x);
        }
        else{
            if(o->ch[0]==NULL) o=o->ch[1];
            else o=o->ch[0];
            delete u;
        }
    }
    else remove(o->ch[d],x);
    if(o!=NULL) o->maintain();
}

int findset(int x){
    return x==pa[x]?x:pa[x]=findset(pa[x]);
}

//把src的结点移动到dest
void mergeto(Node* &src,Node* &dest){
    if(src->ch[0]!=NULL) mergeto(src->ch[0],dest);
    if(src->ch[1]!=NULL) mergeto(src->ch[1],dest);
    insert(dest,src->v);
    delete src;
    src=NULL;
}

int kth(Node* o,int k){
    if(o==NULL||k<=0||k>o->s) return 0;
    int s=(o->ch[1]==NULL?0:o->ch[1]->s);
    if(k==s+1) return o->v;
    else if(k<=s) return kth(o->ch[1],k);
    else return kth(o->ch[0],k-s-1);
}

void add_edge(int x){
    int u=findset(edge[x].from),v=findset(edge[x].to);
    if(u!=v){
        if(root[u]->s<root[v]->s){
            pa[u]=v;
            mergeto(root[u],root[v]);
        }
        else{
            pa[v]=u;
            mergeto(root[v],root[u]);
        }
    }
}

void query(int x,int k){
    query_cnt++;
    query_tot+=kth(root[findset(x)],k);
}

void change_weight(int x,int v){
    int u=findset(x);
    remove(root[u],weight[x]);
    insert(root[u],v);
    weight[x]=v;
}

void removetree(Node* x){
    if(x->ch[0]!=NULL) removetree(x->ch[0]);
    if(x->ch[1]!=NULL) removetree(x->ch[1]);
    delete x;
    x=NULL;
}

int main(){
    freopen("in.txt","r",stdin);
    int cas=0;
    while(scanf("%d%d",&N,&M)!=EOF&&(N||M)){
        for(int i=1;i<=N;i++) scanf("%d",&weight[i]);
        for(int i=1;i<=M;i++) scanf("%d%d",&edge[i].from,&edge[i].to);
        memset(removed,0,sizeof(removed));
        K=0;
        int x,k,v;
        while(scanf("%s",str),str[0]!='E'){
            k=v=0;
            scanf("%d",&x);
            if(str[0]=='D') removed[x]=1;
            else if(str[0]=='Q') scanf("%d",&k);
            //k->v
            else if(str[0]=='C'){
                scanf("%d",&v);
                k=weight[x];
                weight[x]=v;
            }
            command[K++]=(Command){str[0],x,k};
        }
        for(int i=1;i<=N;i++){
            pa[i]=i;
            if(root[i]!=NULL) removetree(root[i]);
            root[i]=new Node(weight[i]);
        }
        for(int i=1;i<=M;i++) if(!removed[i]){
            add_edge(i);
        }
        query_tot=query_cnt=0;
        for(int i=K-1;i>=0;i--){
            if(command[i].op=='D') add_edge(command[i].x);
            else if(command[i].op=='Q') query(command[i].x,command[i].k);
            else if(command[i].op=='C') change_weight(command[i].x,command[i].k);
        }
        printf("Case %d: %.6lf\n",++cas,query_tot/(double)query_cnt);
    }
    return 0;
}




从零搭建ECG心电图仪:模拟前端电路设计与噪声对抗实战 在电子工程和生物医学信号处理领域,微弱信号的采集与放大是核心挑战。其基本原理在于利用高精度模拟电路,从强大的环境噪声中提取出有用的差分信号。这项技术的核心价值在于将理论上的传感器信号转化为稳定、可靠的可用数据,是连接物理世界与数字系统的关键桥梁。在医疗监护、工业传感和科学测量等场景中,高性能的模拟前端设计直接决定了整个系统的精度与可靠性。本文聚焦于生物电信号采集这一具体应用,深入探讨如何运用差分放大器、低通滤波器和陷波滤波器等经典模块,构建一个能够有效对抗工频干扰和接触噪声的实用电路,最终实现从人体体表清晰 阅读详情

相关推荐

【车辆仿真】从0开始建立dSPACE RT Simulink工程:输出模拟电平

0基础建议先看下前面的博文,补充基础知识。原来的博文太长太复杂,后续我会逐步梳理改进,去除操作层面的内容,仅关注知识层面,提升系列博文的系统性。【工程环境信息】:上位机:惠普台式PC(Windows 11专业版)下位机(实时机):SCALEXIO RTPC板卡:DS2680。

winnizap的博客 2054

LA 5031 - Graph and Queries

You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the beginning. You're also given a sequence of operations and you nee

GAUSS_CLB 882

告别裸机:在FreeRTOS上为STM32移植SOEM 1.4.0的完整指南

本文详细介绍了在FreeRTOS环境下为STM32H7系列芯片移植SOEM 1.4.0的完整指南,涵盖环境准备、任务架构设计、OSAL层适配及网络驱动优化等关键步骤。通过EtherCAT主站解决方案的实现,帮助开发者构建稳定可靠的工业自动化系统,提升实时通信性能。

weixin_33582311的博客 363

hdu3726 Graph and Queries

http://www.elijahqi.win/2018/02/25/hdu3726/ Problem Description You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the ...

Elijahqi 351

使用Android GPS api 实现一个轨迹记录的小功能

引入 市场上的跑步软件已经是非常多了,如咕咚和悦跑圈还有其他,很多大厂也在涉足这个方面。而最简单的运动跑步,最近几年也因简单,不限场地,运动效果出众备受大众喜欢。 我的这篇文章的内容很多也是从网上学习其他的博客内容,外加利用android自身的提供的api实现的,希望能对有这方面需求的朋友有所帮助。 介绍 先上两张图,界面比较丑,不过一些数据基本都有了,这个图片是临时要用截取的,所以轨迹线很短,之前

尝试着去了解代码 1万+

NE555构成多谐振荡器及三角波、正弦波的生成(附工程文件)

NE555构成多谐振荡器及三角波、正弦波的生成 续上一篇:NE555基本原理及相关公式的推导

qq_49979053的博客 5万+

HDU3726 UVA1749 Graph and Queries

Graph and Queries Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2264 Accepted Submission(s): 510 Problem Description You are given

eeeaaaaa的专栏 563

影刀RPA之成绩批量查询系统

自动化登录账号,读取数据表中内容去填写信息去查询,并判断多个数据不同的页面去不同的读取查询结果内容,如考生各项信息与各科成绩,总分和查询时间,采集出来到指定的数据表格中,等待时间并依次循环运行。主要功能。

2201_75330891的博客 1082

HDU 3726 Graph and Queries

Description You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the beginning. You're also given a sequence of operation

Occult 1210

科研党必备!用Requests+BeautifulSoup升级版Nature爬虫(含PDF下载功能)

本文介绍了一套基于Python Requests和BeautifulSoup的Nature期刊智能爬虫系统,专为科研人员设计,可自动抓取论文标题、摘要及开放获取的PDF文档。系统采用模块化设计,包含请求管理、PDF检测和邮件通知等功能,确保高效合规地获取学术资源,提升科研效率。

weixin_29041767的博客 254

本地部署 Anything LLM+Ollama+DeepSeek R1 大模型并实现外部访问

DeepSeek 一经发布就引起社会的广泛的关注,因为 DeepSeek 的价格低廉,性能卓越,提供了多种使用方式,满足不同用户的需求和场景。本文将详细的介绍如何在本地 Windows 上安装部署 Anything LLM + Ollama 来实现用户和 DeepSeek-r1 对话的功能以及利用路由侠内网穿透实现外网访问。

lyxnwct的博客 1895

UVA 1479 Graph and Queries(Treap:名次树+并查集)

UVA 1479 Graph and Queries(Treap:名次树+并查集) 题意:给你一个无向图,每个顶点具有权值,现在对图进行操作,你需要输出最后查询操作的平均值.有查询,删除边,改变点的权值三种操作. 分析:刘汝佳训练指南P234例题.        首先读入所有的操作,点以及边.由于只需要我们输出最后的一个平均结果,所以我们把这些操作逆序处理,使得从图中删除边,变成往图中添加边

code 1673

Zynq7000双核裸机开发实战:如何安全实现共享内存与乒乓RAM设计

本文深入探讨了Zynq7000双核裸机开发中的共享内存与乒乓RAM设计,重点解析了核间通信的Cache一致性处理机制和硬件级实现方案。通过实战代码示例和性能优化技巧,帮助开发者解决双核运行中的访问冲突问题,提升嵌入式系统开发效率。

weixin_29191669的博客 375

UVa 1479 (Treap 名次树) Graph and Queries

这题写起来真累。。 名次树就是多了一个附加信息记录以该节点为根的树的总结点的个数,由于BST的性质再根据这个附加信息,我们可以很容易找到这棵树中第k大的值是多少。 所以在这道题中用一棵名次树来维护一个连通分量。 由于图中添边比较方便,用并查集来表示连通分量就好了,但是删边不太容易实现。 所以,先把所有的边删去,然后逆序执行命令。当然,C命令也要发生一些变化,比如说顺序的情况是从a变成b,那...

weixin_30526593的博客 110

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

UVa1479 - Graph and Queries图询问(Treap名次树)

为什么大家写200行的题我要写400行才过啊QAQ。。。。。 详解在代码注释中 这题真的写了好久 从自己写完到、调试到和刘汝佳的标程核对 前后花了半上午+一下午时间QAQ 程序见下 很长确实,但是可读性我觉得比别人是高了很多的#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <

VOCACODE 659

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Graph and Queries UVA - 1479

我真的太开心了!我 AC 了这道这道题困扰了我好久, 我学了 Treap 之后做的第一道题就是这个, 今天!我花费了1.5个小时 AC 了这道题!不看蓝书的代码, 不 ctj!这给了我一个启示: 努力后的汗水像甘霖一样滋润!好了, 废话不多说, 开始解决这道题.

2401_89382924的博客 1029

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

uva 1479 - Graph and Queries(伸展树)

题目链接:uva 1479 - Graph and Queries 题目大意:有一张m条边的无向图,每个节点都有一个权值,现在有若干个操作, D x:删除ID为x的节点Q x k:计算与节点x联通的节点当中,第k大的权值C x v:把节点x的权值改为v 解题思路:把所有操作反过来处理,先执行所有的D操作,获得最终的图,然后逆操作的时候对于D来说即为合并操作,Q和C则是查询和修改操

不慌不忙、不急不躁 1372

UVA 1479 - Graph and Queries(Treap)

UVA 1479 - Graph and Queries 题目链接 题意:给定一个n个结点m条边的无向图,每个结点一个权值,现在有3种操作 D x,删除id为x的边 Q x k 计算与x结点的连通分量中第k大的数字,不存在就是0 C x v 把x结点权值改为v 要求计算所有Q操作的和除以Q操作的次数的值 思路:Treap的经典题,进行离线操作,把操作全部逆向进行,删边

Remilia's 1170

UVA 1479 Graph and Queries(Treap树)

首先把最终图弄出来,然后逆序命令即可。#include struct Node{ Node *ch[2]; int v,r,s; Node(int v): v(v) {ch[0]=ch[1]=NULL;r=rand();s=1;} int cmp(int x) const { if(x==v) return -1; return x<

qq_33901573的博客 254

UVA1479 Graph and Queries

思路 恶心人的题目 还是类似永无乡一题的Treap启发式合并思路 但是由于加边变成了删边 所以应该离线后倒序处理 数组要开够 代码 #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #include <set> #include <s...

weixin_34082177的博客 107

【treap tree】 HDOJ 3726 && LA 5031 && UVA 1479 Graph and Queries

在线转离线。。先构建出

yysys 642

splay<题目续集>

HDU 3436 Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4506Accepted Submission(s): 1232 Problem Description Ponyo and Ga...

weixin_30328063的博客 470

codeforces 246 D. Colorful Graph (set)

D. Colorful Graph You've got an undirected graph, consisting of n vertices and m edges. We will consider the graph's vertices numbered with integers from 1 to n. Each vertex of the graph has

R 1037

LA 5031 Graph and Queries (【名次树(treap)】+【并查集】+【离线算法】)

题目链接:https://cn.vjudge.net/problem/UVALive-5031You are given an undirected graph with N vertexes and M edges. Every vertex in this graph has an integer value assigned to it at the beginning. You’re al

linlinsong—ACM界蒟水! 510
上一篇: uva12206 - Stammering Aliens 哈希LCP和后缀数组两种做法
下一篇: 伸展树
小小小小葱
博客等级 码龄14年 22粉丝 266原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值