题解:

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

  1. CF-1093 (2019/02/10)

    CF-1093 1093A - Dice Rolling 输出x/2即可 #include<bits/stdc++.h> using namespace std; int main() { ...

  2. CF1093:E. Intersection of Permutations(树状数组套主席树)

    题意:给定长度为N的a数组,和b数组,a和b都是1到N的排列: 有两种操作,一种是询问[L1,R1],[L2,R2]:即问a数组的[L1,R1]区间和b数组的[L2,R2]区间出现了多少个相同的数字. ...

随机推荐

  1. HTTP与HTTPS(转)

    一.什么是HTTP? 什么是HTTPS?  HTTP:(Hyper Text Transfer Protocol 超文本传输协议) HTTPS:(Hyper Text Transfer Protoco ...

  2. 【洛谷P2756】飞行员配对方案问题

    题目大意:二分图匹配裸题. 题解:用网络流进行处理. 找配对方案的时候,采用遍历二分图左边的每个节点,找到不与源点相连,且正向边权值为 0,反向边权值为 1 的边,输出即可. 代码如下 #includ ...

  3. javaWeb使用百度编辑器上传图片的问题

    1.先看项目结构(访问网站:http://localhost:8080/baidu_edit/) 2.部署6个jar包 1)先将jsp/lib的6个jar包放入到WEB-INF/lib文件夹中 2)然 ...

  4. DataTable某一列转换为分隔字符串

    //把DataTable的某一列转化为逗号分隔字符串 private static string DataTableColumnSplit(DataTable dataTable,string str ...

  5. :focus-within伪类选择器的3种应用

    1.点击form里任意input隐藏form以外内容提高用户体验 <form><input type="text"></form> form { ...

  6. JAVA的抽象类和接口

    抽象类 在面向对象的概念中,所有的对象都是通过类来描述的,但是反过来,并不是所有的类都是用来描述对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不能实例化对 ...

  7. ubuntu 装机必备

    在github上下载高博的slambook(https://github.com/gaoxiang12/slambook)在3rdparty文件夹中有安装包. 1. 安装Eigen库 sudo apt ...

  8. LeetCode第二十一题-对两个有序链表排序

    Merge Two Sorted Lists 问题简介:合并两个已排序的链表并将其作为新链表返回 举例: 输入: 1->3->5, 1->2->4 输出: 1->1-&g ...

  9. Sublime Text 3删除插件

    Ctrl+Shift+P调出命令窗口,输入remove: 选择第二个Remove Package,会看到如下界面: 里面列出了你已经安装的插件,之后选择你想要卸载的就好了.

  10. L2-006 树的遍历 (25 分)

    链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456 题目: 给定一棵二叉树的后序遍历和中序 ...