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]区间出现了多少个相同的数字. ...
随机推荐
- jmeter笔记(8)--关联
关联是jmeter中比较重要的一个点,在测试过程中有些数据是经常发生变化的,要获取这些数据,就需要使用关联,Jmeter可以通过“后置处理器”中的“正则表达式提取器”来处理关联.. 正则表达式提取器 ...
- 【洛谷P1090 合并果子】
题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...
- 关于AI
自己看着办吧 http://tieba.baidu.com/p/6008409988?fr=ala0&pstaala=1&tpl=5&fid=93764&isgod=0
- Apache的安装与配置+PHP
https://blog.csdn.net/u012130971/article/details/79284937 文件夹名称不要有空格
- WebDriver下载地址
http://chromedriver.storage.googleapis.com/index.html https://blog.csdn.net/ccggaag/article/details/ ...
- c编译动态库可以编译但是无法导入解决方法
$(CC) $(CFLAGS) -Wl,--whole-archive ${libusb} -Wl,--no-whole-archive $(lib_objs) $(LFLAGS) -o $(lib) ...
- HBase RowKey与索引设计
1. HBase的存储形式 hbase的内部使用KeyValue的形式存储,其key时rowKey:family:column:logTime,value是其存储的内容. 其在region内大多以升序 ...
- HBase读写的几种方式(三)flink篇
1. HBase连接的方式概况 主要分为: 纯Java API读写HBase的方式: Spark读写HBase的方式: Flink读写HBase的方式: HBase通过Phoenix读写的方式: 第一 ...
- ubuntu18系统美化
1. 将选定的背景图片 login-bg.jpg 移动到 /usr/share/backgrounds/ 目录下 sudo mv currentdir/mypicture.jpg /usr/share ...
- Future of Future
innovation 革新 , <社会创新实验室 宣传片>的个人记录(有加戏便于我自己理解) 1. 清洁能源 => sustainable 家. 2. 老龄化 => 外出接 ...