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的更多相关文章

  1. hdu 1789 Doing HomeWork Again (贪心算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789 /*Doing Homework again Time Limit: 1000/1000 MS ...

  2. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  4. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  5. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  6. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  7. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  8. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

  9. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

随机推荐

  1. Java多态性详解 (父类引用子类对象)

    面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据. 继承是为了重用父类代码,同时为实现多态性作准备.那么什么是多 ...

  2. nlp_tool

    http://www.afenxi.com/post/9700 11款开放中文分词引擎大比拼 附录评测数据地址http://bosonnlp.com/dev/resource 各家分词系统链接地址Bo ...

  3. swt进度条 线程

    import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import java.util.Rando ...

  4. (linux)container_of()宏

      在学习Linux驱动的过程中,遇到一个宏叫做container_of. 该宏定义在include/linux/kernel.h中,首先来贴出它的代码: /**  * container_of - ...

  5. 【bzoj3282】Tree

    LCT模板题: 话说xor和的意思是所有数xor一下: #include<iostream> #include<cstdio> #include<cstring> ...

  6. Bootloader与Kernel间参数传递机制 taglist【转】

    本文转载自:http://blog.csdn.net/tommy_wxie/article/details/9187821 Tag list被用来在bootloader和Linux kernel 之间 ...

  7. POJ2243 Knight Moves —— A*算法

    题目链接:http://poj.org/problem?id=2243 Knight Moves Time Limit: 1000MS   Memory Limit: 65536K Total Sub ...

  8. MySQL性能优化-I/O相关配置参数

    本文介绍InnoDB和MyISAM两种存储引擎的I/O相关参数配置. 1.InnoDB  I/O相关配置 Innodb是一种事务型的存储引擎,为了减少提交事务时产生的io开销,innodb采用了写日志 ...

  9. 【Java】通过移除空行和注释来压缩 JavaScript 代码

    1. [代码]JavaScriptCompressor.java/** * This file is part of the Echo Web Application Framework (herei ...

  10. CA服务器的搭建

    CA (Certification Authority) 是认证机构的国际通称,它是对数字证书的申请者发放.管理.取消数字证书的机构.CA的作用是检查证书持有者身份的合法性,并签发证书(用数学方法在证 ...