F. 数学上来先打表
题解:
搞这题搞了一天
思维不是很难
就是暴力压位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. 数学上来先打表的更多相关文章
- LibreOJ β Round #2 F. 数学上来先打表
传送门 题解 做法与题解基本无异,不过他说用vector我觉得用链表来得更好一些. #include<queue> #include<ctime> #include<bi ...
- 汕头市队赛 SRM10 T3 数学上来先打表
数学上来先打表 SRM 10 描述 给出 n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案:1.每条边连接两个不同的点,每两个点之间至多有一条边2.不存在三个点a,b,c使三个点间两两 ...
- 【STSRM10】数学上来先打表
[算法]DP+数学计数 [题意]给出n个点(不同点之间有区别),求出满足下列条件的连边(双向边)方案(对1004535809取模): 1.每条边连接两个不同的点,每两个点之间至多有一条边. 2.不存在 ...
- [loj519]数学上来先打表
建立操作树,即1和3操作时i-1向i连边,2操作中k向i连边,然后dfs一遍 那么当我们走到一个节点,就执行该操作(修改也是操作),退出后取消该操作即可 于是相当于要维护一个东西,支持:1.加边:2. ...
- 数学--数论--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 ...
- [国家集训队]整数的lqp拆分 数学推导 打表找规律
题解: 考场上靠打表找规律切的题,不过严谨的数学推导才是本题精妙所在:求:$\sum\prod_{i=1}^{m}F_{a{i}}$ 设 $f(i)$ 为 $N=i$ 时的答案,$F_{i}$ 为斐波 ...
- 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- ...
- 【NOIP模拟赛】 permutation 数学(打表)
biubiu~~~ 这道题卡读题卡得很死......首先他告诉我们读循环的时候要顺着圈读,然后又说这个圈在数列上要以最大数开始读,而且以这样的循环的首数排序,得到的序列与原序列一样那么他就是可行序列, ...
- Latex数学符号对应表
1. 希腊字母 字母 实现 字母 实现 $\alpha$ \alpha $\Alpha$ \Alpha $\beta$ \beta $\Beta$ \Beta $\gamma$ \gamma $\Ga ...
随机推荐
- C/C++中可变参数函数的实现
在C语言的stdarg.h头文件中提供了三个函数va_start, va_end,va_arg和一个类型va_list.利用它们,我们可以很容易实现一个可变参数的函数.首先简单介绍一下这三个函数. 假 ...
- Codeforces 914D - Bash and a Tough Math Puzzle 线段树,区间GCD
题意: 两个操作, 单点修改 询问一段区间是否能在至多一次修改后,使得区间$GCD$等于$X$ 题解: 正确思路; 线段树维护区间$GCD$,查询$GCD$的时候记录一共访问了多少个$GCD$不被X整 ...
- matlab常用命令
clc; %清屏 clear; %清除变量 close all; %关闭 doc %查看文档 meshgrid%采样mesh %网格曲面surf %光滑曲面plot %ezplotdiff figur ...
- 让NotePad++添加到右键快捷方式
添加后的效果图: 操作方式: 第一步:在桌面上新建一个txt文本文档,然后将写入如下内容 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT ...
- __new__方法和pop方法(判断)
new方法(构造方法)是在函数一加载的时候就被执行,在init方法执行之前被执行 def __new__(cls,*args,**kwargs): if kwargs.pop('many',False ...
- Spring+SpringMVC+MyBatis的整合
1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-On ...
- mongo 的导入和导出
1.导出工具:mongoexport 1.概念: mongoDB中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指 ...
- React-Native到0.44版本后Navigator 不能用的问题
新升级 到0.46版本以后 Navigator 不能使用报错. 'Navigator is deprecated and has been removed from this package. It ...
- Linux 用户(user)和用户组(group)管理概述
一.理解Linux的单用户多任务,多用户多任务概念: Linux 是一个多用户.多任务的操作系统:我们应该了解单用户多任务和多用户多任务的概念: 1.Linux 的单用户多任务:单用户多任务:比如我们 ...
- 【linux】ssh无法root免密解决
在设置了root的私钥和公钥,添加authorized_keys,修改文件权限为600后,用root账号 ssh localhost结果失败了,还是要密码. 解决: vim /etc/ssh/sshd ...