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]区间出现了多少个相同的数字. ...
随机推荐
- net core swagger接口
net swagger接口 引用NuGet包 Install-Package Swashbuckle.AspNetCore //控制台 Microsoft.Extensions.PlatformAbs ...
- React踩坑记
一: Support for the experimental syntax 'classProperties' isn't currently enabled ERROR in ./src/inde ...
- 把xml数据直接插入到sqlserver数据库
存储过程: ALTER proc [ali].[ins_冻结金额表] @xmldoc varchar(max), ) as declare @idoc int exec sp_xml_prepared ...
- Vue学习笔记四:跑马灯效果
目录 跑马灯原理 HTML 箭头函数 计时器 跑马灯效果 跑马灯原理 先讲讲跑马灯的原理,就是一行字,会滚动,思路是这样的,使用substring方法,一个获取字符串的第一个字,一个获取1后面所有的字 ...
- 安装python的pywin32安装不了,提示找不到py3.6-32
安装python的pywin32安装不了,提示找不到py3.6-32 首先我自己的py3.6是64位版本的,这是pywin32模块的下载地址 里面有各种版本的,首先我先下了64位的3.6版本的,结果提 ...
- Redis实战(十)Redis常见问题及解决方案
序言
- JAVA集合1--总体框架
JAVA集合是JAVA提供的工具包,包含了常用的数据结构:集合.链表.栈.队列.数组.映射等.JAVA集合工具包的位置是java.util.* JAVA集合主要可以分为4个部分:List.Set.Ma ...
- Swift 4 Hex Color
上点干货,写个extension, 可以通过hex值去设置Color,以及通过UIColor的color case 去得到hex值. extension UIColor { var toHex ...
- spring 4 + hibernate 4 配置数据库事务
配置事务时应该加载aopalliance-1.0.jar和aspectjweaver.jar这两个包,这两个包是必须的.
- git add . 提示 `Changes not staged for commit`