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 ...
随机推荐
- 简单的glib测试(三)
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <locale.h&g ...
- 浅谈JavaScript的函数表达式(递归)
递归函数,在前面的博客中已经简单的介绍了.递归函数是一个通过函数名称在函数内部调用自身的函数.如下: function fac(num){ if(num<1){ return 1; } else ...
- debian old version cd and distribution archives
1 debian old version cd/dvd 官网的old version image,下载速度很慢 http://cdimage.debian.org/cdimage 下面这个靠谱,是镜像 ...
- download file by python in google colab
https://stackoverflow.com/questions/15352668/download-and-decompress-gzipped-file-in-memory You need ...
- vue开发购物车,解决全选单选问题
实现全选单选,在vue中无法通过this获取input中的checkbox的checked属性,但是可以通过vue对input的特殊方式v-model来实现对应数据的绑定,同样也可以通过这种方式实现购 ...
- 【转载】AsyncTask用法
在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行.在单线程模型中始终要记住两条法则: 1. 不要阻塞UI线程 2. 确保只 ...
- C#参数数组的用法1
C# 参数数组 有时,当声明一个方法时,您不能确定要传递给函数作为参数的参数数目.C# 参数数组解决了这个问题,参数数组通常用于传递未知数量的参数给函数. params 关键字 在使用数组作为形参时, ...
- [SHOI 2009] 会场预约
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2028 [算法] 直接用std :: set维护即可 时间复杂度 : O(NlogN) ...
- 关于GitHub的DNS基础设施,你了解吗?
在 GitHub,我们最近从头改进了 DNS.这包括了我们如何与外部 DNS 提供商交互以及我们如何在内部向我们的主机提供记录.为此,我们必须设计和构建一个新的 DNS 基础设施,它可以随着 GitH ...
- String、StringBuffer和StringBuilder有什么区别?
1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间.String a = "a&quo ...