热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【treaptree】HDOJ3726&&LA5031&&UVA1479GraphandQueries

在线转离线。。先构建出最终的图,然后逆着处理。。不过有几个要注意的地方。。。答案超int,要用longlong。。逆着处理的时候C操作要反着操作。。求第k大的时候,k可能是0或负数,也可能超过

在线转离线。。先构建出最终的图,然后逆着处理。。不过有几个要注意的地方。。。答案超int,要用long long。。逆着处理的时候C操作要反着操作。。求第k大的时候,k可能是0或负数,也可能超过集合元素个数。。

#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include 
#include 
#include 
#define maxn 20005
#define eps 1e-10
#define mod 1000000009
#define INF 99999999  
#define lowbit(x) (x&(-x))  
//#define lson o<<1, L, mid  
//#define rson o<<1 | 1, mid+1, R  
typedef long long LL;
//typedef int LL;
using namespace std;

int value[maxn], n, m;
char s[100];
struct Edge
{
	int u, v, done;
}edges[60005];
struct opr
{
	int kk, x, y;
}op[1000005];
int opp, cnt;
LL ans;
int f[maxn], num[maxn];
struct node
{
	int key, v, s;
	struct node *ch[2];
	int cmp(int x) const {
		if(x == v) return -1;
		return x s + ch[1]->s + 1;
	}
}*null, *root[maxn];

void read(void)
{
	opp = 0;
	for(int i = 1; i <= n; i++) scanf("%d", &value[i]);
	for(int i = 1; i <= m; i++) scanf("%d%d", &edges[i].u, &edges[i].v), edges[i].dOne= 0;
	while(scanf("%s", s)!=EOF) {
		if(s[0] == 'E') break;
		if(s[0] == 'D') op[opp].kk = 0, scanf("%d", &op[opp++].x), edges[op[opp-1].x].dOne= 1;
		if(s[0] == 'Q') op[opp].kk = 1, scanf("%d%d", &op[opp].x, &op[opp].y), opp++;
		if(s[0] == 'C') op[opp].kk = 2, scanf("%d%d", &op[opp].x, &op[opp].y), swap(op[opp].y, value[op[opp].x]), opp++;
	}
}
void init(void)
{
	int i;
	ans = cnt = 0;
	for(i = 0; i s = null->v = 0;
	for(i = 0; i <= n; i++) {
		root[i] = new node;
		root[i] = null;
	}
}
int find(int x)
{
	return f[x] == x ? f[x] : find(f[x]);
}
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;
		o->key = rand(), o->v = x;
		o->s = 1, o->ch[0] = o->ch[1] = null;
		return;
	}
	int d = x v ? 0 : 1;
	insert(o->ch[d], x);
	if(o->key ch[d]->key) rotate(o, d^1);
	o->maintain();
}
void remove(node* &o, int x)
{
	int d = o->cmp(x);
	if(d == -1) {
		if(o->ch[0] != null && o->ch[1] != null) {
			int d2 = (o->ch[0]->key > o->ch[1]->key ? 1 : 0);
			rotate(o, d2), remove(o->ch[d2], x);
		}
		else {
			node *u = o;
			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 kth(node *o, int k)
{
	if(o == null || o->s ch[1]->s >= k) return kth(o->ch[1], k);
	if(o->ch[1]->s + 1 == k) return o->v;
	return kth(o->ch[0], k - o->ch[1]->s - 1);
}
void debug(node* o)
{
	printf("FSDF  %d\n", o->v);
	if(o->ch[0] != null) debug(o->ch[0]);
	if(o->ch[1] != null) debug(o->ch[1]);
}
void removetree(node* &o, node* &p)
{
	if(o == null) return;
	if(o->ch[0] != null) removetree(o->ch[0], p);
	if(o->ch[1] != null) removetree(o->ch[1], p);
	insert(p, o->v);
	delete o;
}
void updata(int a, int v)
{
	int aa = find(a);
	remove(root[aa], value[a]);
	value[a] = v;
	insert(root[aa], value[a]);
}
void query(int a, int k)
{
	int aa = find(a);
	ans += kth(root[aa], k);
}
void merge(int a, int b)
{
	int aa = find(a), bb = find(b);
	if(aa == bb) return;
	if(num[aa] > num[bb]) {
		removetree(root[bb], root[aa]);
		f[bb] = aa, num[aa] += num[bb], num[bb] = 0;
		root[bb] = null;
	}
	else {
		removetree(root[aa], root[bb]);
		f[aa] = bb, num[bb] += num[aa], num[aa] = 0;
		root[aa] = null;
	}
}
void work(void)
{
	int i, aa, bb;
	for(i = 1; i <= m; i++)
		if(!edges[i].done) {
			aa = find(edges[i].u);
			bb = find(edges[i].v);
			if(aa != bb) {
				if(aa > bb) f[aa] = bb, num[bb] += num[aa], num[aa] = 0;
				else f[bb] = aa, num[aa] += num[bb], num[bb] = 0;
			}
		}
	for(i = 1; i <= n; i++) insert(root[find(i)], value[i]);
	for(i = opp-1; i >= 0; i--) {
		if(op[i].kk == 0) merge(edges[op[i].x].u, edges[op[i].x].v);
		if(op[i].kk == 1) query(op[i].x, op[i].y), cnt++;
		if(op[i].kk == 2) updata(op[i].x, op[i].y);
	}
}
int main(void)
{
	int _ = 0;
	while(scanf("%d%d", &n, &m), n!=0 || m!=0) {
		init();
		read();
		work();
		printf("Case %d: %.6f\n", ++_, ans/(double)cnt);
	}
	return 0;
}



推荐阅读
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • Codeforces Round #566 (Div. 2) A~F个人题解
    Dashboard-CodeforcesRound#566(Div.2)-CodeforcesA.FillingShapes题意:给你一个的表格,你 ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 本文深入探讨了POJ2762问题,旨在通过强连通分量缩点和单向连通性的判断方法,解决有向图中任意两点之间的可达性问题。文章详细介绍了算法原理、实现步骤,并附带完整的代码示例。 ... [详细]
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • C++: 实现基于类的四面体体积计算
    本文介绍如何使用C++编程语言,通过定义类和方法来计算由四个三维坐标点构成的四面体体积。文中详细解释了四面体体积的数学公式,并提供了两种不同的实现方式。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本题涉及一棵由N个节点组成的树(共有N-1条边),初始时所有节点均为白色。题目要求处理两种操作:一是改变某个节点的颜色(从白变黑或从黑变白);二是查询从根节点到指定节点路径上的第一个黑色节点,若无则输出-1。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 本题旨在通过给定的评级信息,利用拓扑排序和并查集算法来确定全球 Tetris 高手排行榜。题目要求判断是否可以根据提供的信息生成一个明确的排名表,或者是否存在冲突或信息不足的情况。 ... [详细]
  • 本文探讨了如何通过最小生成树(MST)来计算严格次小生成树。在处理过程中,需特别注意所有边权重相等的情况,以避免错误。我们首先构建最小生成树,然后枚举每条非树边,检查其是否能形成更优的次小生成树。 ... [详细]
author-avatar
走丢的鞋带2702934823
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有