题解:

搞这题搞了一天

思维不是很难

就是暴力压位bitset

分块做法速度更快

但是stl里的不能实现这个功能

所以手动实现

64位压一位

到65535跑一下1的个数

然后(x>>16)&65535+...计算出1的个数

眼查错果然还是不靠谱以后还是写对拍吧

另外的难点在于这题很卡空间

我们建立dfs树

这样把总空间变为最大消耗空间

合并bitset的时候我们利用启发式合并

并且bitset只存出现了的位置

就是那些64位都没有出现的就不存了

空间是nlogn的,但是还是挺卡的吧

使用动态开数组的技巧替代vector

*int=calloc(大小,sizeof())

另外这个东西不会自动释放空间

所以我们要free()这个东西

代码:

#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define rint int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const int N=1.1e5;
struct bi{
ull *v;
int *pos,cnt;
bi() { cnt=;}
}B[N];
int head[N],count2[N],count3[N],pos[N],pos2[N],pos3[N],pos4[N],fa[N],ans[N];
IL void js2(bi &a,bi b,int p)
{
if (p==)
{
int sad;
sad=;
}
bi c;
int tmp=a.cnt+b.cnt;
c.v=(ull*)calloc(tmp+,sizeof(ull));
c.pos=(int*)calloc(tmp+,sizeof(int));
rint x=a.cnt,y=b.cnt;
c.cnt=;
rint i=,j=;
while (i<=x&&j<=y)
{
if (a.pos[i]<b.pos[j]) c.v[++c.cnt]=a.v[i],c.pos[c.cnt]=a.pos[i],i++;
else if (a.pos[i]>b.pos[j]) c.v[++c.cnt]=b.v[j],c.pos[c.cnt]=b.pos[j],j++;
else
{
// if (a.v[i]^b.v[j])
c.v[++c.cnt]=a.v[i]^b.v[j],c.pos[c.cnt]=b.pos[j];
i++; j++;
}
}
while (j<=y) c.v[++c.cnt]=b.v[j],c.pos[c.cnt]=b.pos[j],j++;
while (i<=x) c.v[++c.cnt]=a.v[i],c.pos[c.cnt]=a.pos[i],i++;
free(a.v); free(a.pos);
a=c;
}
struct re{
int a,b,c,d;
}e[N*],a[N];
bool cmp(re x,re y)
{
return(x.a<y.a);
}
int l;
void arr(int x,int y,int x1,int y1)
{
e[++l].a=head[x];
e[l].b=y;
e[l].c=x1;
e[l].d=y1;
head[x]=l;
}
#define js(x) (count2[x&65535]+count2[(x>>16)&65535]+count2[(x>>32)&65535]+count2[(x>>48)&65535])
int find(int x)
{
return fa[x]==x?x:find(fa[x]);
}
vector<re> ve[N];
void dfs(int x)
{
int l=(int)(ve[x].size())-;
rep(i,,l)
{
int x1=pos4[find(ve[x][i].a)],x2=ve[x][i].b,x3=ve[x][i].c;
int cnt=;
rep(i,,B[x1].cnt)
if (cnt+js(B[x1].v[i])<x2)
cnt+=js(B[x1].v[i]);
else
{
ull o=B[x1].v[i];
rep(j,,)
if ((o>>j)&)
{
cnt++;
if (cnt==x2)
{
ans[x3]=*(B[x1].pos[i]-)+j+; break;
}
}
break;
}
if (cnt<x2) ans[x3]=-;
}
for (rint u=head[x];u;u=e[u].a)
{
rint v=e[u].b;
rint x1=find(e[u].c),x2=find(e[u].d),tmp=;
// bi tmp2;
bool tt=;
if (x1!=x2)
{
tt=;
if (count3[x1]>count3[x2]) swap(x1,x2);
fa[x1]=x2; count3[x2]+=count3[x1];
int k1=B[pos4[x1]].cnt,k2=B[pos4[x2]].cnt;
if (k1>k2)
{
tmp=pos4[x2];
// tmp2=B[pos4[x1]];
js2(B[pos4[x1]],B[pos4[x2]],);
pos4[x2]=pos4[x1];
} else
js2(B[pos4[x2]],B[pos4[x1]],pos4[x2]);
}
dfs(v);
if (tt)
{
fa[x1]=x1; count3[x2]-=count3[x1];
if (tmp)
{
pos4[x2]=tmp; js2(B[pos4[x1]],B[tmp],);
} else
{
js2(B[pos4[x2]],B[pos4[x1]],pos4[x2]);
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
rep(i,,) count2[i]=count2[i>>]+(i&);
int n,m;
cin>>n>>m;
rep(i,,n) cin>>a[i].a,a[i].b=i;
rep(i,,n) pos4[i]=i,count3[i]=;
sort(a+,a+n+,cmp);
rep(i,,n) pos[a[i].b]=i,pos2[i]=a[i].a;
rep(i,,n)
{
B[i].v=(ull*)calloc(,sizeof(ull)); B[i].pos=(int*)calloc(,sizeof(int));
int t=pos[i]; t--;
B[i].pos[]=(t/)+; B[i].v[]=1ull<<(t%);
fa[i]=i;
B[i].cnt=;
}
int now,cnt,cnt2=;
now=cnt=;
pos3[]=;
rep(i,,m)
{
int kk,x,y;
cin>>kk;
if (kk==)
{
cin>>x>>y;
arr(now,++cnt,x,y);
pos3[i]=cnt;
now=cnt;
}
if (kk==)
{
cin>>x;
now=pos3[x];
}
if (kk==)
{
cin>>x>>y;
ve[now].push_back((re){x,y,++cnt2});
}
pos3[i]=now;
}
dfs();
rep(i,,cnt2)
if (ans[i]==-) cout<<-<<endl;
else cout<<pos2[ans[i]]<<endl;
return ;
}

F. 数学上来先打表的更多相关文章

  1. LibreOJ β Round #2 F. 数学上来先打表

    传送门 题解 做法与题解基本无异,不过他说用vector我觉得用链表来得更好一些. #include<queue> #include<ctime> #include<bi ...

  2. 汕头市队赛 SRM10 T3 数学上来先打表

    数学上来先打表 SRM 10 描述 给出 n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案:1.每条边连接两个不同的点,每两个点之间至多有一条边2.不存在三个点a,b,c使三个点间两两 ...

  3. 【STSRM10】数学上来先打表

    [算法]DP+数学计数 [题意]给出n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案(对1004535809取模): 1.每条边连接两个不同的点,每两个点之间至多有一条边. 2.不存在 ...

  4. [loj519]数学上来先打表

    建立操作树,即1和3操作时i-1向i连边,2操作中k向i连边,然后dfs一遍 那么当我们走到一个节点,就执行该操作(修改也是操作),退出后取消该操作即可 于是相当于要维护一个东西,支持:1.加边:2. ...

  5. 数学--数论--HDU 2582 F(N) 暴力打表找规律

    This time I need you to calculate the f(n) . (3<=n<=1000000) f(n)= Gcd(3)+Gcd(4)+-+Gcd(i)+-+Gc ...

  6. [国家集训队]整数的lqp拆分 数学推导 打表找规律

    题解: 考场上靠打表找规律切的题,不过严谨的数学推导才是本题精妙所在:求:$\sum\prod_{i=1}^{m}F_{a{i}}$ 设 $f(i)$ 为 $N=i$ 时的答案,$F_{i}$ 为斐波 ...

  7. HDU 2802 F(N) 数论+打表

    题目大意:f[n]-n^3=f[n-2]-(n-1)^3 (n >=3),f[1]=1,f[2]=7,求f[n]. 题目思路:将n^3移到到等式右边化简的到:f[n]=f[n-2]+3n*(n- ...

  8. 【NOIP模拟赛】 permutation 数学(打表)

    biubiu~~~ 这道题卡读题卡得很死......首先他告诉我们读循环的时候要顺着圈读,然后又说这个圈在数列上要以最大数开始读,而且以这样的循环的首数排序,得到的序列与原序列一样那么他就是可行序列, ...

  9. Latex数学符号对应表

    1. 希腊字母 字母 实现 字母 实现 $\alpha$ \alpha $\Alpha$ \Alpha $\beta$ \beta $\Beta$ \Beta $\gamma$ \gamma $\Ga ...

随机推荐

  1. 一道并查集的(坑)题:关闭农场closing the farm

    题目描述 in English: Farmer John and his cows are planning to leave town for a long vacation, and so FJ ...

  2. WebSocket参考

    websocker是一种网页和服务端建立tcp全双工通信的技术,可以不再让页面进行向服务器发送轮询请求. 需要注意使用的场景,如果建立的tcp过多的话,会对服务器有很大压力. WebSocket前后台 ...

  3. spring aop -包的问题

    Caused by: java.lang.NoSuchMethodError: org.springframework.aop.framework.AopProxyUtils.getSingleton ...

  4. linux进程内存布局

      一个程序本质上都是由 BSS 段.data段.text段三个组成的.这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分 ...

  5. 手机端上点击input框软键盘出现时把input框不被覆盖,显示在屏幕中间(转)

    转载地址:https://www.cnblogs.com/xzzzys/p/7526761.html 1  用定位为题来解决var oHeight = $(document).height(); // ...

  6. PID控制器开发笔记之七:微分先行PID控制器的实现

    前面已经实现了各种的PID算法,然而在某些给定值频繁且大幅变化的场合,微分项常常会引起系统的振荡.为了适应这种给定值频繁变化的场合,人们设计了微分先行算法. 1.微分先行算法的思想 微分先行PID控制 ...

  7. Oracle 查询优化的基本准则详解

      注:报文来源:想跌破记忆寻找你 < Oracle 查询优化的基本准则详解 > Oracle 查询优化的基本准则详解 1:在进行多表关联时,多用 Where 语句把单个表的结果集最小化, ...

  8. jQuery获取地址栏中的链接参数

    http://caibaojian.com/177.html 问题描述 今天做一个主题,有一个需求是根据不同的页面来做,虽然php也可以做到,不过考虑到自己的特效代码都是在jQuery上完成,想着能否 ...

  9. respberry2b + android5.1

    链接: http://pan.baidu.com/s/1kUf6UtL 密码: xz4g 安装教程:http://tieba.baidu.com/p/3963061007 如果安装后打开相册崩溃,则下 ...

  10. Java语法基础常见疑惑解答

    1. 类是java的最小单位,java的程序必须在类中才能运行 2. java函数加不加static有何不同 java中声明为static的方法称为静态方法或类方法.静态方法可以直接调用静态方法,访问 ...