CF1093
题解:
D:
比较显然这个图得是二分图才行
然后每个二分图上的方案是$(2^a+2^b) (a,b是两种颜色的个数)$
E:
我tm就不该先写bitset的
正解和bitset都很好想
因为是个排列,所以所有元素都不同,会有很多性质
bitset就是我们对序列维护一个前缀和表示前i位有哪些数
发现你开不下空间
于是分块一下
复杂度 $n\sqrt{n}+\frac{nm}{32}$
写了没多久卡常数卡了3个小时,然后还没过。。(题解说是不想让它过得。。)
大概是
把bitset换成了手写 循环展开
询问用4个矩形减一减改成两个减一减再做&运算(这个在我本机快了很多 可提交上去影响并不大 不知道为什么)
另外真没发现指针比数组快。。我感觉一般都比数组慢
不过那个4次访问数组把它先用个变量存下来能快一点
cf的机子开不开O2啊。。我这开O2本机跑全是询问的也才7s啊。。
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for(int i=h;i<=t;i++)
#define dep(i,t,h) for(int i=t;i>=h;i--)
#define ll long long
#define me(x) memset(x,0,sizeof(x))
#define mep(x,y) memcpy(x,y,sizeof(y))
#define mid ((h+t)>>1)
#define ull unsigned long long
namespace IO{
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T> void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
char sr[<<],z[]; ll Z,C1=-;
template<class T>void wer(T x)
{
if (x<) sr[++C1]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C1]=z[Z],--Z);
}
IL void wer1()
{
sr[++C1]=' ';
}
IL void wer2()
{
sr[++C1]='\n';
}
template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
template<class T>IL void mina(T &x,T y) {if (x>y) x=y;}
template<class T>IL T MAX(T x,T y){return x>y?x:y;}
template<class T>IL T MIN(T x,T y){return x<y?x:y;}
};
using namespace IO;
const int N=2.1e5+;
const int M=;
const int l=N/+;
int ans[];
struct Bitset{
ull a[l+];
IL void operator = (const Bitset o)
{
register int i;
for (i=;i+<=l;i+=)
{
a[i]=o.a[i];
a[i+]=o.a[i+];
a[i+]=o.a[i+];
a[i+]=o.a[i+];
a[i+]=o.a[i+];
a[i+]=o.a[i+];
a[i+]=o.a[i+];
a[i+]=o.a[i+];
}
for (;i<=l;i++) a[i]=o.a[i];
}
IL Bitset operator & (Bitset &o)
{
Bitset c;
register int i;
for (i=;i+<=l;i+=)
{
c.a[i]=o.a[i]&a[i];
c.a[i+]=o.a[i+]&a[i+];
c.a[i+]=o.a[i+]&a[i+];
c.a[i+]=o.a[i+]&a[i+];
c.a[i+]=o.a[i+]&a[i+];
c.a[i+]=o.a[i+]&a[i+];
c.a[i+]=o.a[i+]&a[i+];
c.a[i+]=o.a[i+]&a[i+];
}
for (;i<=l;i++) c.a[i]=o.a[i]&a[i];
return c;
}
IL Bitset operator ^ (Bitset &o)
{
Bitset c;
register int i;
for (i=;i+<=l;i+=)
{
c.a[i]=o.a[i]^a[i];
c.a[i+]=o.a[i+]^a[i+];
c.a[i+]=o.a[i+]^a[i+];
c.a[i+]=o.a[i+]^a[i+];
c.a[i+]=o.a[i+]^a[i+];
c.a[i+]=o.a[i+]^a[i+];
c.a[i+]=o.a[i+]^a[i+];
c.a[i+]=o.a[i+]^a[i+];
}
for (;i<=l;i++) c.a[i]=o.a[i]&a[i];
return c;
}
IL int count()
{
int ansl=;
register int i;
for (i=;i+<=l;i+=)
{
ull x0=a[i],x1=a[i+],x2=a[i+],x3=a[i+],x4=a[i+],x5=a[i+],x6=a[i+],x7=a[i+];
ansl+=ans[(x0&)]+ans[(x0>>)&]
+ans[(x0>>)&]+ans[(x0>>)&];
ansl+=ans[(x1&)]+ans[(x1>>)&]
+ans[(x1>>)&]+ans[(x1>>)&];
ansl+=ans[(x2&)]+ans[(x2>>)&]
+ans[(x2>>)&]+ans[(x2>>)&];
ansl+=ans[(x3&)]+ans[(x3>>)&]
+ans[(x3>>)&]+ans[(x3>>)&];
ansl+=ans[(x4&)]+ans[(x4>>)&]
+ans[(x4>>)&]+ans[(x4>>)&];
ansl+=ans[(x5&)]+ans[(x5>>)&]
+ans[(x5>>)&]+ans[(x5>>)&];
ansl+=ans[(x6&)]+ans[(x6>>)&]
+ans[(x6>>)&]+ans[(x6>>)&];
ansl+=ans[(x7&)]+ans[(x7>>)&]
+ans[(x7>>)&]+ans[(x7>>)&];
}
for (;i<=l;i++) ansl+=ans[(a[i]&)]+ans[(a[i]>>)&]
+ans[(a[i]>>)&]+ans[(a[i]>>)&];
return ansl;
}
IL void set(int x,int y)
{
int pos=(x-)/+;
int k=x-pos*;
if (y==) a[pos]|=1ll<<(k-);
else a[pos]|=1ll<<(k-),a[pos]^=1ll<<(k-);
}
};
int a[N],b[N],pos[N],n,m,block,num;
Bitset a1[M],b1[M];
void reset(int x)
{
a1[x]=a1[x-]; b1[x]=b1[x-];
int h1=(x-)*block+,t1=MIN(n,x*block);
rep(i,h1,t1) a1[x].set(a[i],),b1[x].set(b[i],);
}
IL int query(int x,int y)
{
if (!x||!y) return();
int x1=pos[x],y1=pos[y];
Bitset nowa=a1[x1-],nowb=b1[y1-];
rep(i,(x1-)*block+,x) nowa.set(a[i],);
rep(i,(y1-)*block+,y) nowb.set(b[i],);
Bitset nowc=nowa&nowb;
return (nowa&nowb).count();
}
Bitset kong;
IL Bitset get_query1(int x)
{
if (!x) return(kong);
int x1=pos[x];
Bitset nowa=a1[x1-];
rep(i,(x1-)*block+,x) nowa.set(a[i],);
return nowa;
}
IL Bitset get_query2(int x)
{
if (!x) return(kong);
int x1=pos[x];
Bitset nowa=b1[x1-];
rep(i,(x1-)*block+,x) nowa.set(b[i],);
return nowa;
}
IL int query(int l1,int r1,int l2,int r2)
{
Bitset k1=get_query1(l1-),k2=get_query1(r1);
k2=k2^k1;
Bitset k3=get_query2(l2-),k4=get_query2(r2);
k4=k4^k3;
return (k2&k4).count();
}
IL int change(int x,int y)
{
int x1=pos[x],y1=pos[y],v1=b[x],v2=b[y];
swap(b[x],b[y]);
rep(i,x1,y1-) b1[i].set(v2,),b1[i].set(v1,);
}
#define lowbit(x) (x&(-x))
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n); read(m);
rep(i,,) ans[i]=ans[i-lowbit(i)]+;
rep(i,,n) read(a[i]);
rep(i,,n) read(b[i]);
block=sqrt(n); num=(n-)/block+;
rep(i,,num) reset(i);
rep(i,,n) pos[i]=(i-)/block+;
rep(i,,m)
{
int kk,l1,r1,l2,r2,x,y;
read(kk);
if (kk==)
{
read(l1); read(r1); read(l2); read(r2);
// wer(query(r1,r2)-query(l1-1,r2)-query(r1,l2-1)+query(l1-1,l2-1));
wer(query(l1,r1,l2,r2));
wer2();
} else
{
read(x); read(y);
if (x>y) swap(x,y);
change(x,y);
}
}
fwrite(sr,,C1+,stdout);
return ;
}
正解也很简单
把每个点对应到第二个序列
变成二维查询点数,单点修改
线段树套线段树/平衡树就可以了
然而这个东西空间很傻比
线段树套线段树不用说肯定gg了
空间比较小的线段树套平衡树
本身空间$nlogn$
然后每个里面要开$ls,rs,num,v$
然后一共插入个数是$n+4*m$的
所以计算一下就是$6e6*logn$的 可能再把ls,rs压压是可以的。。
比较简单又最快的方法是用cdq分治再套个数据结构
#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (int i=h;i<=t;i++)
#define dep(i,t,h) for (int i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
#define ll long long
#define mep(x) memcpy(x,y,sizeof(y))
#define mid ((h+t)>>1)
namespace IO{
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T>void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
char sr[<<],z[]; int Z,C=-;
template<class T>void wer(T x)
{
if (x<) sr[++C]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C]=z[Z],--Z);
}
IL void wer1() {sr[++C]=' ';}
IL void wer2() {sr[++C]='\n';}
template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;}
template<class T>IL void mina(T &x,T y) { if (x>y) x=y;}
template<class T>IL T MAX(T x,T y) {return x>y?x:y;}
template<class T>IL T MIN(T x,T y) {return x<y?x:y;}
};
const int N=3e5;
const int M=N*;
int a[N],b[N],c[N],d[N],e[N],ans[N],n,m;
struct re{
int a,b,c,d;
}p[M],p1[M],p2[M];
#define lowbit(x) (x&(-x))
struct BIT{
int sum[N];
int query(int x)
{
int ans=;
for (int y=x;y>;y-=lowbit(y)) ans+=sum[y];
return ans;
}
void change(int x,int k)
{
for (;x<=n;x+=lowbit(x)) sum[x]+=k;
}
}B;
bool cmp(re x,re y){
return x.a<y.a;
}
void cdq_fz(int h,int t)
{
if (h==t) return;
int cnt1=,cnt2=;
rep(i,h,mid)
if (p[i].c<=) p1[++cnt1]=p[i];
rep(i,mid+,t)
if (p[i].c>=)
{
p2[++cnt2]=p[i];
}
sort(p1+,p1+cnt1+,cmp);
sort(p2+,p2+cnt2+,cmp);
int t1=;
rep(i,,cnt2)
{
while (t1<=cnt1&&p1[t1].a<=p2[i].a) B.change(p1[t1].b,p1[t1].c),t1++;
ans[p2[i].d]+=(p2[i].c-)*B.query(p2[i].b);
}
dep(i,t1-,) B.change(p1[i].b,-p1[i].c);
cdq_fz(h,mid);
cdq_fz(mid+,t);
}
bool t[N];
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
IO::read(n); IO::read(m);
rep(i,,n) IO::read(a[i]),e[a[i]]=i;
rep(i,,n) IO::read(b[i]),c[b[i]]=i;
rep(i,,n) d[i]=c[a[i]];
int num=;
rep(i,,n) p[++num]=(re){i,d[i],,i};
rep(i,,m)
{
int kk,x1,y1,x2,y2,x,y;
IO::read(kk);
if (kk==)
{
t[i]=;
IO::read(x1); IO::read(x2); IO::read(y1); IO::read(y2);
p[++num]=(re){x2,y2,,i};
p[++num]=(re){x2,y1-,,i};
p[++num]=(re){x1-,y2,,i};
p[++num]=(re){x1-,y1-,,i};
} else
{
IO::read(x); IO::read(y);
p[++num]=(re){e[b[x]],x,-,i};
p[++num]=(re){e[b[x]],y,,i};
p[++num]=(re){e[b[y]],y,-,i};
p[++num]=(re){e[b[y]],x,,i};
swap(b[x],b[y]);
}
}
cdq_fz(,num);
rep(i,,m) if (t[i]) IO::wer(ans[i]),IO::wer2();
fwrite(IO::sr,,IO::C+,stdout);
return ;
}
F:
G:
第一眼感觉很像kd-tree呀(n那么大跑啥kd-tree啊)
正解很好想
因为k只有5,所以我们对符号讨论一下维护最大最小值就好了
$nlogn*32$
CF1093的更多相关文章
- CF-1093 (2019/02/10)
CF-1093 1093A - Dice Rolling 输出x/2即可 #include<bits/stdc++.h> using namespace std; int main() { ...
- CF1093:E. Intersection of Permutations(树状数组套主席树)
题意:给定长度为N的a数组,和b数组,a和b都是1到N的排列: 有两种操作,一种是询问[L1,R1],[L2,R2]:即问a数组的[L1,R1]区间和b数组的[L2,R2]区间出现了多少个相同的数字. ...
随机推荐
- 树莓派wiringPi,BCM,BOARD编码对应管脚
wiringPi,BCM,BOARD编码 由于上课需要, 嵌入式学习从树莓派开始 树莓派中执行: $> gpio readall 即可得到关于树莓派管脚的各种信息 上面的图可能不是特别清楚, 可 ...
- table的 noWrap 属性不换行
nowrap是什么意思? HTML中td元素的nowrap属性表示禁止单元格中的文字自动换行. 但使用时要注意的是,td元素noWrap属性的行为与td元素的width属性有关. td元素中nowra ...
- Nacos环境搭建
先去下载↓↓↓↓ https://github.com/alibaba/nacos/releases 单机版 单机版主要为了测试,没啥意思,你下载一个zip包,然后解压,进入bin目录,双击 star ...
- docker 基础之监控
docker容器监控命令 docker ps 命令(查看所有的运行中的容器) docker stats 命令(容器状态监控) [root@bogon ~]# docker stats containe ...
- Vue学习笔记七:Vue中的样式
目录 两种样式 class样式 内联样式 两种样式 Vue中使用样式方式有两种,一种是class样式,一种是内联样式也就是style class样式 class样式使用的方式有5种,HTML如下 &l ...
- Visual Studio Code Shortcuts
https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf https://code.visualstudio.com ...
- CentOS命令登录MySQL时,报错ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)错误解决方法
1.停用mysql服务:# /etc/rc.d/init.d/mysqld stop 2.输入命令:# mysqld_safe --user=mysql --skip-grant-tables --s ...
- linux 查看/修改jdk版本
linux 查看/修改jdk版本 配置环境变量vim /etc/profile 编辑profile文件 在底部加入JAVA_HOME=/usr/java/jdk1.8PATH=$JAVA_HOME/b ...
- TP5架构下链接SQL数据库的一种方法
1.database设置 2.连接到所需要的表格 *.数据库目录
- php nginx 负载均衡简单配置过程
负载均衡 负载均衡是我们大流量网站要做的一个东西,下面我来给大家介绍在Nginx服务器上进行负载均衡配置方法,希望对有需要的同学有所帮助哦. 简单了解一下什么是负载均衡,单从字面上的意思来理解就可以解 ...