您的位置:首页 > 其它

洛谷P3613 睡觉困难综合征

2017-04-21 09:11 330 查看

题目背景

刚立完Flag我就挂了WC和THUWC。。。

时间限制0.5s,空间限制128MB

因为Claris大佬帮助一周目由乃通过了Deus的题,所以一周目的由乃前往二周目世界找雪辉去了

由于二周目世界被破坏殆尽,所以由乃和雪辉天天都忙着重建世界(其实和MC差不多吧),Deus看到了题问她,总是被告知无可奉告

Deus没办法只能去三周目世界问三周目的由乃OI题。。。

三周目的世界中,因为没有未来日记,所以一切都很正常,由乃天天认真学习。。。

因为Deus天天问由乃OI题,所以由乃去学习了一下OI

由于由乃智商挺高,所以OI学的特别熟练

她在RBOI2016中以第一名的成绩进入省队,参加了NOI2016获得了金牌保送

5 10 5
2 4
1 9
3 9
3 15
1 7
1 2
1 4
2 5
2 3
1 1 3 31
1 1 5 31
1 4 3 28
1 3 4 28
1 5 4 27
1 4 5 27
1 5 4 27
1 4 3 28
1 3 4 28
hack  

↑由于这个贪心顺序的问题,reverse的时候不能打个lazy标记就走,需要向下push一层。没注意到这个问题,多调了一个小时。

 

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<bitset>
#include<vector>
#define LL unsigned long long
using namespace std;
const int mxn=100010;
LL read(){
LL x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
vector<int>ve[mxn];
struct node{
int ch[2],fa;
LL val;
int tp;//位运算方式
bool rev;
}t[mxn];
struct table{
bitset<64>f[2];//真值表 //哪些位置填0/1能得到1
}a[mxn],b[mxn],f[mxn];
inline bool isroot(int x){
return t[t[x].fa].ch[0]!=x && t[t[x].fa].ch[1]!=x;
}
void init(bitset<64> &a,LL b,int tp){
bitset<64> B=b;
if(tp==1){a=a&B;}//&
else if(tp==2){a=a|B;}//|
else if(tp==3){a=a^B;}//^
return;
}
table calc(const table &x,const table &y){
bitset<64>B,C;
B=(x.f[0]&y.f[1])|((~x.f[0])&y.f[0]);
C=(x.f[1]&y.f[1])|((~x.f[1])&y.f[0]);
return (table){B,C};
}
void update(int rt){
a[rt]=f[rt];b[rt]=f[rt];
int ls=t[rt].ch[0],rs=t[rt].ch[1];
if(ls){
a[rt]=calc(a[ls],a[rt]);b[rt]=calc(b[rt],b[ls]);
}
if(rs){
a[rt]=calc(a[rt],a[rs]);b[rt]=calc(b[rs],b[rt]);
}
return;
}
void rever(int x){
t[x].rev^=1;
int &lc=t[x].ch[0],&rc=t[x].ch[1];
swap(lc,rc);
swap(a[x],b[x]);
return;
}
void PD(int x){
if(t[x].rev){
rever(t[x].ch[0]);
rever(t[x].ch[1]);
t[x].rev=0;
}
return;
}
void rotate(int x){
int y=t[x].fa,z=t[y].fa,lc,rc;
if(t[y].ch[0]==x)lc=0;else lc=1; rc=lc^1;
if(!isroot(y))
t[z].ch[t[z].ch[1]==y]=x;
t[x].fa=z;t[y].fa=x;
t[t[x].ch[rc]].fa=y;
t[y].ch[lc]=t[x].ch[rc];
t[x].ch[rc]=y;
update(y);
return;
}
int st[mxn],top=0;
void Splay(int x){
st[top=1]=x;
for(int i=x;!isroot(i);i=t[i].fa)st[++top]=t[i].fa;
while(top)PD(st[top--]);
while(!isroot(x)){
int y=t[x].fa,z=t[y].fa;
if(!isroot(y)){
if((t[y].ch[0]==x)^(t[z].ch[0]==y))rotate(y);
else rotate(x);
}
rotate(x);
}
update(x);
return;
}
void access(int x){
for(int y=0;x;x=t[x].fa){
Splay(x);
t[x].ch[1]=y;
update(x);
y=x;
}
return;
}
int dfn[mxn];
void mkroot(int x){
access(x);Splay(x);
rever(x);
return;
}
void change(int x,int y,LL z){
access(x);   Splay(x);
t[x].tp=y;  t[x].val=z;
f[x].f[1].set(); f[x].f[0].reset();
init(f[x].f[0],t[x].val,t[x].tp);
init(f[x].f[1],t[x].val,t[x].tp);
update(x);
return;
}
void query(int x,int y,LL z){
mkroot(x);access(y);Splay(y);
LL ans=0,now=0;
for(int i=63;i>=0;i--){
if(a[y].f[0][i]==1){
ans+=1LL<<i;
}
else if(a[y].f[1][i]==1){
if(now+(1LL<<i)<=z){
now+=1LL<<i;
ans+=1LL<<i;
}
}
}
printf("%llu\n",ans);
return;
}
int n,m,K;
void solve(){
int Q,x,y;LL z;
for(int i=1;i<=m;i++){
Q=read();x=read();y=read();scanf("%llu",&z);
if(Q==1)
query(x,y,z);
else
change(x,y,z);
}
return;
}
void Build(int x,int fa){
for(int i=0;i<ve[x].size();i++){
if(ve[x][i]==fa)continue;
t[ve[x][i]].fa=x;
Build(ve[x][i],x);
}
return;
}
int main(){
int i,j;
n=read();m=read();K=read();
for(i=1;i<=n;i++){
t[i].tp=read();
t[i].val=read();
f[i].f[1].set();
init(f[i].f[0],t[i].val,t[i].tp);
init(f[i].f[1],t[i].val,t[i].tp);
}
int u,v;
for(i=1;i<n;i++){
u=read();v=read();
ve[u].push_back(v); ve[v].push_back(u);
}
Build(1,0);
solve();
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: