Luogu P5352 Terrible Homework
神仙@TheLostWeak出的题,因为他最近没时间所以我先写一下sol(其实我也没什么时间)
作为一道简单的数据结构题想必大家都能看出必须用LCT维护信息吧
一个朴素的想法就是直接维护四种操作的值,但是这样修改除了异或好像都不能维护
既然一个\(\log\)不可行那么就大力两个\(\log\)吧,很容易想到直接把信息拆分成二进制来存,然后记一下子树内所有数每一位上\(1\)的个数和
同时我们再维护一个子树大小,那么对于每种询问时直接大力枚举每一位的情况判断即可:
and
:判断这一位上\(1\)的个数是否等于子树大小or
:判断这一位上是否有\(1\)xor
:判断这一位上\(1\)的个数的奇偶性sum
:大力累加起来就好了
具体的,修改的时候由于是异或操作,因此直接把对应要变的那一位\(0,1\)的个数调换,即用子树大小减去\(1\)的个数
然后还需要下传标记,这个直接lazy tag维护一下就好了,类似于Luogu P1501 [国家集训队]Tree II
然后我们就把这道水水的送分题写完了,LCT由于是板子所以会比较长,其实是核心代码是很短的
CODE
#include<cstdio>
#include<cctype>
#define RI register int
#define CI const int&
#define Tp template <typename T>
using namespace std;
typedef long long LL;
const int N=100005,RG=30;
int n,m,val[N],x,y,z; char opt;
class FileInputOutput
{
private:
static const int S=1<<21;
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
#define pc(ch) (Ftop<S?Fout[Ftop++]=ch:(fwrite(Fout,1,S,stdout),Fout[(Ftop=0)++]=ch))
char Fin[S],Fout[S],*A,*B; int Ftop,pt[25];
public:
Tp inline void read(T& x)
{
x=0; char ch; while (!isdigit(ch=tc()));
while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
}
inline void get_alpha(char& ch)
{
while (!isalpha(ch=tc()));
}
Tp inline void write(T x)
{
if (!x) return (void)(pc('0'),pc('\n')); RI ptop=0;
while (x) pt[++ptop]=x%10,x/=10; while (ptop) pc(pt[ptop--]+48); pc('\n');
}
inline void Fend(void)
{
fwrite(Fout,1,Ftop,stdout);
}
#undef tc
#undef pc
}F;
class Link_Cut_Tree
{
private:
struct splay
{
int ch[2],fa,s[RG],size,tag; bool rev;
}node[N]; int stack[N],top;
#define lc(x) node[x].ch[0]
#define rc(x) node[x].ch[1]
#define fa(x) node[x].fa
#define S(x,y) node[x].s[y]
#define SZ(x) node[x].size
#define R(x) node[x].rev
#define T(x) node[x].tag
inline void swap(int& x,int& y)
{
int t=x; x=y; y=t;
}
inline void rever(CI now)
{
swap(lc(now),rc(now)); R(now)^=1;
}
inline void upt(CI now,CI xv)
{
for (RI i=0;i<RG;++i) if ((xv>>i)&1)
S(now,i)=SZ(now)-S(now,i); val[now]^=xv; T(now)^=xv;
}
inline void pushup(CI now)
{
SZ(now)=SZ(lc(now))+SZ(rc(now))+1; for (RI i=0;i<RG;++i)
S(now,i)=S(lc(now),i)+S(rc(now),i)+((val[now]>>i)&1);
}
inline void pushdown(CI now)
{
if (R(now)) rever(lc(now)),rever(rc(now)),R(now)=0;
if (T(now)) upt(lc(now),T(now)),upt(rc(now),T(now)),T(now)=0;
}
inline int identify(CI now)
{
return rc(fa(now))==now;
}
inline void connect(CI x,CI y,CI d)
{
node[fa(x)=y].ch[d]=x;
}
inline bool isroot(CI now)
{
return lc(fa(now))!=now&&rc(fa(now))!=now;
}
inline void rotate(CI now)
{
int x=fa(now),y=fa(x),d=identify(now); if (!isroot(x)) node[y].ch[identify(x)]=now;
fa(now)=y; connect(node[now].ch[d^1],x,d); connect(x,now,d^1); pushup(x); pushup(now);
}
inline void splay(int now)
{
int t=now; while (stack[++top]=t,!isroot(t)) t=fa(t);
while (top) pushdown(stack[top--]); for (;!isroot(now);rotate(now))
t=fa(now),!isroot(t)&&(rotate(identify(now)!=identify(t)?now:t),0);
}
inline void access(int x)
{
for (int y=0;x;x=fa(y=x)) splay(x),rc(x)=y,pushup(x);
}
inline void makeroot(CI now)
{
access(now); splay(now); rever(now);
}
inline int findroot(int now)
{
for (access(now),splay(now);lc(now);now=lc(now)) pushdown(now); return splay(now),now;
}
inline void split(CI x,CI y)
{
makeroot(x); access(y); splay(y);
}
public:
inline void build(void)
{
for (RI i=1;i<=n;++i) for (RI j=0;j<RG;++j) S(i,j)=(val[i]>>j)&1;
}
inline void link(CI x,CI y)
{
makeroot(x); if (findroot(y)!=x) fa(x)=y;
}
inline void cut(CI x,CI y)
{
makeroot(x); if (findroot(y)==x&&fa(y)==x&&!lc(y)) rc(x)=fa(y)=0; pushup(x);
}
inline void modify_xor(CI x,CI y,CI z)
{
split(x,y); upt(y,z);
}
inline int query_and(CI x,CI y,int ret=0)
{
split(x,y); for (RI i=0;i<RG;++i)
if (S(y,i)==SZ(y)) ret|=1<<i; return ret;
}
inline int query_or(CI x,CI y,int ret=0)
{
split(x,y); for (RI i=0;i<RG;++i)
if (S(y,i)) ret|=1<<i; return ret;
}
inline int query_xor(CI x,CI y,int ret=0)
{
split(x,y); for (RI i=0;i<RG;++i)
if (S(y,i)&1) ret|=1<<i; return ret;
}
inline LL query_sum(CI x,CI y,LL ret=0)
{
split(x,y); for (RI i=0;i<RG;++i)
ret+=1LL*(1<<i)*S(y,i); return ret;
}
#undef lc
#undef rc
#undef fa
#undef S
#undef SZ
#undef R
#undef T
}LCT;
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (F.read(n),F.read(m),i=1;i<=n;++i) F.read(val[i]);
for (LCT.build(),i=1;i<=m;++i)
{
F.get_alpha(opt); F.read(x); F.read(y);
switch (opt)
{
case 'L':
LCT.link(x,y); break;
case 'C':
LCT.cut(x,y); break;
case 'U':
F.read(z); LCT.modify_xor(x,y,z); break;
case 'A':
F.write(LCT.query_and(x,y)); break;
case 'O':
F.write(LCT.query_or(x,y)); break;
case 'X':
F.write(LCT.query_xor(x,y)); break;
case 'S':
F.write(LCT.query_sum(x,y)); break;
}
}
return F.Fend(),0;
}
Luogu P5352 Terrible Homework的更多相关文章
- bzoj 4320: ShangHai2006 Homework
4320: ShangHai2006 Homework Time Limit: 10 Sec Memory Limit: 128 MB Description 1:在人物集合 S 中加入一个新的程序员 ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- HDU 1789 Doing Homework again(贪心)
Doing Homework again 这只是一道简单的贪心,但想不到的话,真的好难,我就想不到,最后还是看的题解 [题目链接]Doing Homework again [题目类型]贪心 & ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
- POJ 2082 Terrible Sets
Terrible Sets Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 2747 Accepted: 1389 Des ...
- hdu-1789-Doing Homework again
/* Doing Homework again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- Terrible Sets_单调栈
Description Let N be the set of all natural numbers {0 , 1 , 2 , . . . }, and R be the set of all re ...
- [luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...
- [luogu P2647] 最大收益(贪心+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...
随机推荐
- TypeScript完全解读(26课时)_18.Mixins混入
本节的代码在mixin.ts文件内 同时在index.ts内引入 混入就是把两个对象或者类的内容混合到一起,从而实现一些功能复用. 对象混入 js中对象的混入 先来看一个js中对象的混入的例子 首先定 ...
- Eclipse如何查看接口实现类快捷键
1.找到要打开的接口类 2.双击接口名选中 3.按Ctrl+T打开接口实现类 以List接口为例,如下所示
- CTP 下单返回错误: 没有报单权限 和字段错误需要注意的问题
没有报单权限一般被认为期货公司没有开权限, 但是更多的问题是没有填写 BrokerId, InvestorId 下单字段错误注意一个容易忽略的地方: a. order 应该全部设为0, b. orde ...
- django框架知识3
1.Django安装: 1.安装版本Django1.11.11 2.安装方式:命令行安装 pycharm安装 2.创建Django项目 1.创建方式:cd到你要创建的目录下 然后输入 Djang ...
- 搭建hustoj现场环境
所需:就用了台普通电脑作为web以及数据库端,两台数据库实验室提供的服务器拿来做评测机. 根据提示将三台都装上hustoj 当然我是用之前比赛遗留下来的judge { 可以用以下来代替 wget ht ...
- 下载devc++和codeblocks记录
dev的安装包自己百度网盘里有 codeblocks官网 下载好后再解压即可,如果不是默认路径安装的话,还会出现检测不到编译器路径问题,解决办法在这.
- java数据结构----堆
1.堆:堆是一种树,由它实现的优先级队列的插入和删除的时间复杂度都是O(logn),用堆实现的优先级队列虽然和数组实现相比较删除慢了些,但插入的时间快的多了.当速度很重要且有很多插入操作时,可以选择堆 ...
- java实现打印正三角,倒三角
正三角代码: package BasicType; /** * 封装一个可以根据用户传入值来打印正三角的方法 * @author Administrator */ public class Enme ...
- Macbook上sublime的C++11弥补bits/stdc++.h的配置
如果在windows配置过的话这次会容易很多.相关博客很多了,我这里保存一下我借鉴并成功的配置: 关于自己build的C++,文件类型为sublime-build,直接扔在它给出的user文件夹即可, ...
- FTP任务(重点看断点续传)
一.FTP任务目录: 1. 多用户同时登陆: socketserver 2. 用户登陆,加密认证: md5加密 3. 上传/下载文件,保证文件一致性:md5摘要 4. 传输过程中现实进度条 5 ...