About set HDU - 4680
https://vjudge.net/problem/HDU-4680
一直想写,终于写完了。。。
要点:
这个set不需要去重
操作4的做法就是暴力枚举取的数(最开始两个取set中最小两个,设这次取的值为now,前一次取的值为last,那么下次要取大于等于now+last的最小数),由于每一次取的值大于等于last的值的两倍,因此枚举次数是logn级别的
错误记录:
1.100行少upd
2.多组数据忘消去内存占用
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
int n,m;
int gcd(int a,int b)
{
if(!a||!b) return a+b;
int t;
while(b)
{
t=a;
a=b;
b=t%b;
}
return a;
}
namespace S
{
#define N 400100
struct Node
{
Node *ch[];
int sz,d,r,n;
int g;
}nds[N];
queue<Node*> q;
int rand1()
{
static int x=;
return x=(48271LL*x+)%;
}
void init()
{
for(int i=;i<N;i++) q.push(nds+i);
}
Node *getnode()
{
Node *t=q.front();q.pop();
t->ch[]=t->ch[]=;t->sz=t->d=t->g=t->n=;t->r=rand1();
return t;
}
void delnode(Node *x) {q.push(x);}
int gsz(Node *o) {return o?o->sz:;}
int gg(Node *o) {return o?o->g:;}
void upd(Node *o)
{
o->g=gcd(gcd(gg(o->ch[]),o->d),gg(o->ch[]));
o->sz=gsz(o->ch[])+o->n+gsz(o->ch[]);
}
Node *merge(Node *a,Node *b)
{
if(!a) return b;
if(!b) return a;
if(a->r<b->r)
{
a->ch[]=merge(a->ch[],b);upd(a);
return a;
}
else
{
b->ch[]=merge(a,b->ch[]);upd(b);
return b;
}
}
typedef pair<Node*,Node*> pnn;
pnn split_x(Node *a,int x)//<=x,>x
{
if(!a) return pnn(,);
pnn y;
if(x<a->d)
{
y=split_x(a->ch[],x);
a->ch[]=y.se;upd(a);y.se=a;
}
else
{
y=split_x(a->ch[],x);
a->ch[]=y.fi;upd(a);y.fi=a;
}
return y;
}
void add(Node *&a,int x,int k)
{
pnn t1=split_x(a,x-),t2=split_x(t1.se,x);
if(!t2.fi)
{
Node *t=getnode();t->d=x;upd(t);
t2.fi=t;
}
t2.fi->n+=k;upd(t2.fi);//upd
if(t2.fi->n==) delnode(t2.fi),t2.fi=;
a=merge(t1.fi,merge(t2.fi,t2.se));
}
int qg(Node *&a,int l,int r)
{
pnn t1=split_x(a,l-),t2=split_x(t1.se,r);
int ans=t2.fi?t2.fi->g:-;
a=merge(t1.fi,merge(t2.fi,t2.se));
return ans;
}
Node *find(Node *a,int x)
{
if(!a) return ;
if(x<a->d) return find(a->ch[],x);
else if(x==a->d) return a;
else return find(a->ch[],x);
}
int upb(Node *a,int x)
{
if(!a) return 0x7fffffff;
if(a->d>x) return min(a->d,upb(a->ch[],x));
else return upb(a->ch[],x);
}
void mergeto(Node *&a,Node *b)//b合并到a上
{
if(!b) return;
mergeto(a,b->ch[]);mergeto(a,b->ch[]);
add(a,b->d,b->n);
delnode(b);
}
void mgto(Node *&a,Node *&b)//b合并到a上,启发式
{
if(gsz(a)<gsz(b)) swap(a,b);
mergeto(a,b);
}
void deltree(Node *o)
{
if(!o) return;
deltree(o->ch[]);deltree(o->ch[]);
delnode(o);
}
}
using S::Node;
using S::add;
using S::upb;
Node *rt[N];
int a[N];
namespace D
{
int fa[N],p[N],num;
void init()
{
int i;num=n;
for(i=;i<=n+m;i++) fa[i]=i,rt[i]=;
for(i=;i<=n;i++)
{
p[i]=i;
add(rt[i],a[i],);
}
}
int findd(int x){return x==fa[x]?x:fa[x]=findd(fa[x]);}
int find(int x){return findd(p[x]);}
void unionn(int x,int y)
{
x=findd(x);y=findd(y);
if(x==y) return;
fa[x]=y;S::mgto(rt[y],rt[x]);
}
void union1(int x,int y){unionn(p[x],p[y]);}
void move(int x,int y)//将x移到y所在集合中
{
if(x==y) return;
add(rt[find(x)],a[x],-);
++num;p[x]=num;unionn(p[x],p[y]);
add(rt[find(x)],a[x],);
}
void change(int x,int y)//x权值改y
{
add(rt[find(x)],a[x],-);
a[x]=y;
add(rt[find(x)],a[x],);
}
}
int main()
{
Node *tt,*r;
int T,TT=,i,ans,u,v,idx,last,now,t,L,R;
S::init();
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=;i<=n;i++) scanf("%d",&a[i]);
++TT;
printf("Case #%d:\n",TT);
D::init();
for(i=;i<=m;i++)
{
scanf("%d",&idx);
if(idx==)
{
scanf("%d%d",&u,&v);
D::union1(u,v);
}
else if(idx==)
{
scanf("%d%d",&u,&v);
D::move(u,v);
}
else if(idx==)
{
scanf("%d%d",&u,&v);
D::change(u,v);
}
else if(idx==)
{
scanf("%d",&u);r=rt[D::find(u)];
if(r->sz<=) ans=r->sz;
else
{
last=upb(r,-);tt=S::find(r,last);
if(tt->n>) now=last;
else now=upb(r,last);
ans=;
while()
{
t=last;last=now;
now=upb(r,t+now-);
if(now==0x7fffffff) break;
ans++;
}
}
printf("%d\n",ans);
}
else if(idx==)
{
scanf("%d%d%d",&u,&L,&R);
printf("%d\n",S::qg(rt[D::find(u)],L,R));
}
}
for(i=;i<=n+m;i++)
if(D::findd(i)==i)
S::deltree(rt[i]);
//printf("%d\n",S::q.size());
}
return ;
}
About set HDU - 4680的更多相关文章
- hdu 1789 Doing HomeWork Again (贪心算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789 /*Doing Homework again Time Limit: 1000/1000 MS ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 3791二叉搜索树解题(解题报告)
1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...
随机推荐
- JavaScript中label语句的使用
之前在读<javascript高级程序设计>的时候,看到过lable语句,当时看完感觉好像很少用到,但是今天,刚好在项目终于到了合适的场景,合理使用label可以大幅度优化性能. 首先来简 ...
- 还在为开发APP发愁? 这里就有现成通用的代码!
1.开源控件 1)首页: 1.1)首先是下拉刷新数据的 SwipeRefreshLayout 地址:https://github.com/hanks-zyh/SwipeRefreshLayout 1. ...
- Leetcode(58)题解:Length of Last Word
https://leetcode.com/problems/length-of-last-word/ 题目: Given a string s consists of upper/lower-case ...
- Java中的文件上传和下载
文件上传原理: 早期的文件上传机制: 在TCP/IP中.最早出现的文件上传机制是FTP.他是将文件由客户端发送到服务器的标准机制. jsp中的文件上传机制: 在jsp编程中不能使用FTP的方法来上传文 ...
- ABAP debug遇到问题
新项目的系统,调试是老出现这个框不断弹出,一堆出来 都来不及关. 不确定是不是因为可用对话框不够的原因.
- JSP 使用 JDBC连接SQL Server
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- eclipse软件启动弹窗端口问题解决
如果启动eclipse,弹出一个窗口,上面显示,8080 .8009.……等的提示,说明端口有冲突, 解决办法如下: 1.打开cmd 2.输入 netstat -ano|findstr 8080 ...
- python数据分组运算
摘要: pandas 的 GroupBy 功能可以方便地对数据进行分组.应用函数.转换和聚合等操作. # 原作者:lionets GroupBy 分组运算有时也被称为 “split-apply-c ...
- wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用
之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里: func (engine *Engine) segmenterWorker() { for { request : ...
- [Selenium] 使用Firefox Driver 示例
//导入Selenium 库和FirefoxDriver 库 package com.learningselenium.simplewebdriver; import org.openqa.selen ...