洛谷P3613 睡觉困难综合征(LCT)
题目:
解题思路:
LCT,主要是维护链上的多位贪心答案,推个公式:分类讨论入0/1的情况,合并就好了(公式是合并用的)
代码(我不知道之前那个为啥一直wa,改成结构体就好了QAQ:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll tr[spc].ch[0] 5 #define rrr tr[spc].ch[1] 6 #define lls tr[spc].dt[0] 7 #define rrs tr[spc].dt[1] 8 #define ls ch[0] 9 #define rs ch[1] 10 #define ll dt[0] 11 #define rr dt[1] 12 #define aa (unsigned long long)(0ull) 13 #define bb (unsigned long long)(~(ul)(0ull)) 14 typedef unsigned long long ul; 15 using std::swap; 16 struct data{ 17 ul v0; 18 ul v1; 19 data friend operator + (data x,data y) 20 { 21 data ans; 22 ans.v0=(~x.v0&y.v0)|(x.v0&y.v1); 23 ans.v1=(~x.v1&y.v0)|(x.v1&y.v1); 24 return ans; 25 } 26 }; 27 struct trnt{ 28 int ch[2]; 29 int fa; 30 int lzt; 31 data val; 32 data dt[2]; 33 bool anc; 34 }tr[1000000]; 35 int n,m,k; 36 ul qcc[1000]; 37 bool whc(int spc) 38 { 39 return tr[tr[spc].fa].rs==spc; 40 } 41 void pushup(int spc) 42 { 43 lls=rrs=tr[spc].val; 44 if(lll) 45 { 46 lls=tr[lll].ll+lls; 47 rrs=rrs+tr[lll].rr; 48 } 49 if(rrr) 50 { 51 lls=lls+tr[rrr].ll; 52 rrs=tr[rrr].rr+rrs; 53 } 54 return ; 55 } 56 void trr(int spc) 57 { 58 if(!spc) 59 return ; 60 swap(lll,rrr); 61 swap(lls,rrs); 62 tr[spc].lzt^=1; 63 return ; 64 } 65 void pushdown(int spc) 66 { 67 if(tr[spc].lzt) 68 { 69 tr[spc].lzt=0; 70 trr(lll); 71 trr(rrr); 72 } 73 return ; 74 } 75 void recal(int spc) 76 { 77 if(!tr[spc].anc) 78 recal(tr[spc].fa); 79 pushdown(spc); 80 return ; 81 } 82 void rotate(int spc) 83 { 84 int f=tr[spc].fa; 85 bool k=whc(spc); 86 tr[f].ch[k]=tr[spc].ch[!k]; 87 tr[spc].ch[!k]=f; 88 if(tr[f].anc) 89 { 90 tr[spc].anc=1; 91 tr[f].anc=0; 92 }else 93 tr[tr[f].fa].ch[whc(f)]=spc; 94 tr[spc].fa=tr[f].fa; 95 tr[f].fa=spc; 96 tr[tr[f].ch[k]].fa=f; 97 pushup(f); 98 pushup(spc); 99 return ; 100 return ; 101 } 102 void splay(int spc) 103 { 104 recal(spc); 105 while(!tr[spc].anc) 106 { 107 int f=tr[spc].fa; 108 if(tr[f].anc) 109 { 110 rotate(spc); 111 return ; 112 } 113 if(whc(spc)^whc(f)) 114 rotate(spc); 115 else 116 rotate(f); 117 rotate(spc); 118 } 119 return ; 120 } 121 void access(int spc) 122 { 123 int lst=0; 124 while(spc) 125 { 126 splay(spc); 127 tr[rrr].anc=1; 128 tr[lst].anc=0; 129 rrr=lst; 130 pushup(spc); 131 lst=spc; 132 spc=tr[spc].fa; 133 } 134 } 135 void Mtr(int spc) 136 { 137 access(spc); 138 splay(spc); 139 trr(spc); 140 return ; 141 } 142 void split(int x,int y) 143 { 144 Mtr(x); 145 access(y); 146 splay(y); 147 return ; 148 } 149 void link(int x,int y) 150 { 151 Mtr(x); 152 tr[x].fa=y; 153 return ; 154 } 155 ul vl(ul a,ul b,int op) 156 { 157 if(op==1) 158 return a&b; 159 if(op==2) 160 return a|b; 161 return a^b; 162 } 163 int main() 164 { 165 scanf("%d%d%d",&n,&m,&k); 166 qcc[0]=1; 167 for(int i=1;i<=k;i++) 168 qcc[i]=qcc[i-1]<<1; 169 ul tmp=qcc[k]-1; 170 for(int i=1;i<=n;i++) 171 { 172 int opt; 173 scanf("%d",&opt); 174 ul x; 175 scanf("%llu",&x); 176 tr[i].anc=1; 177 int spc=i; 178 lls.v0=rrs.v0=tr[i].val.v0=vl(0,x,opt); 179 lls.v1=rrs.v1=tr[i].val.v1=vl(tmp,x,opt); 180 } 181 for(int i=1;i<n;i++) 182 { 183 int a,b; 184 scanf("%d%d",&a,&b); 185 link(a,b); 186 } 187 while(m--) 188 { 189 int cmd; 190 scanf("%d",&cmd); 191 if(cmd==1) 192 { 193 int x,y; 194 scanf("%d%d",&x,&y); 195 split(x,y); 196 ul z; 197 scanf("%llu",&z); 198 ul ans=0; 199 ul tmp0=tr[y].ll.v0; 200 ul tmp1=tr[y].ll.v1; 201 for(int i=k-1;i>=0;i--) 202 { 203 if(qcc[i]&tmp0) 204 ans|=qcc[i]; 205 else if((qcc[i]&tmp1)&&z>=qcc[i]) 206 { 207 z-=qcc[i]; 208 ans|=qcc[i]; 209 } 210 } 211 printf("%llu\n",ans); 212 }else{ 213 int x,y; 214 scanf("%d%d",&x,&y); 215 ul z; 216 scanf("%llu",&z); 217 splay(x); 218 tr[x].val.v0=vl(z,0,y); 219 tr[x].val.v1=vl(z,tmp,y); 220 pushup(x); 221 } 222 } 223 return 0; 224 }