社区讨论
求卡常方法
P6781 [Ynoi2008] rupq参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mbwcbcny
- 此快照首次捕获于
- 2025/06/14 22:36 8 个月前
- 此快照最后确认于
- 2025/11/04 07:10 4 个月前
rt,已经大战此题整整20h,惨遭卡常,求有没有好的卡常方法
FHQ-Treap 和 Splay 都试了一遍,都卡不过去
本地测试已经从20s卡到6s
FHQ:
CPP#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define Ckmax(x,y) x=max(x,y)
#define Ckmin(x,y) x=min(x,y)
#define ull unsigned long long
#define uint unsigned int
using namespace std;
const int N=2e6+5;
const int IINF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3fll;
inline void FileIO(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
}
template<typename Type>
inline void read(Type &res){
Type x=0,f=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
res=x*f;
}
mt19937 seed(time(0));
const uint FUL=0xffffffff;
int n,Q;
bool a[N];
uint b[N];
int val[N];
struct Data{
uint s0,s1,mx;
friend Data operator + (Data x,Data y){
return Data{(x.s0&y.s1)|((~x.s0)&y.s0),(x.s1&y.s1)|((~x.s1)&y.s0),max(x.mx,y.mx)};
}
}EPT;
#define Init(x) Data{FUL,~(x),(x)}
#define likely(x) __builtin_expect(!!(x),1)
struct FHQTreap{
int ls,rs,pri;
int cl,cr;
int x; uint v;
Data vl,vr,rst;
int siz;
}tr[N];
int root;
void Print(int p){
if(!p) puts("EMPTY");
else
printf("Tr[%d]: ls=%d,rs=%d,Bs=(%d,%d),V=(%d,%d),Vl=%u,Vr=%u,Rst=%u,Siz=%d\n",p,tr[p].ls,tr[p].rs,tr[p].cl,tr[p].cr,tr[p].x,tr[p].v,tr[p].vl.mx,tr[p].vr.mx,tr[p].rst.mx,tr[p].siz);
}
void Print(int p,string s,bool fir){
cout<<s<<(fir?"+---":"\\---"); Print(p);
if(!p) return;
s+=(fir?"| ":" ");
Print(tr[p].ls,s,1);
Print(tr[p].rs,s,0);
}
Data AskL(int p,int k){
if(!p||tr[p].cl<=k) return EPT;
if(!k) return tr[p].vl;
Data res=EPT;
while(1){
if(!p||tr[p].cl<=k) break;
if(!k){res=tr[p].vl+res;break;}
int pls=tr[p].ls,prs=tr[p].rs;
int cl=tr[pls].cl+max(0,(!tr[p].x)-tr[pls].cr);
int cr=tr[p].x+max(0,tr[pls].cr-(!tr[p].x));
if(likely(cl<=k)) p=prs,k=k-cl+cr;
else{
res=tr[prs].rst+res;
if(likely(!tr[p].x&&!tr[pls].cr)) res=Init(tr[p].v)+res;
p=pls;
}
}
return res;
}
Data AskR(int p,int k){
if(!p||tr[p].cr<=k) return EPT;
if(!k) return tr[p].vr;
Data res=EPT;
while(1){
if(!p||tr[p].cr<=k) break;
if(!k){res=res+tr[p].vr;break;}
int pls=tr[p].ls,prs=tr[p].rs;
int cl=(!tr[p].x)+max(0,tr[prs].cl-tr[p].x);
int cr=tr[prs].cr+max(0,tr[p].x-tr[prs].cl);
if(likely(cr<=k)) p=pls,k=k-cr+cl;
else{
res=res+tr[pls].rst;
if(likely(tr[p].x&&!tr[prs].cl)) res=res+Init(tr[p].v);
p=prs;
}
}
return res;
}
inline void Pushup(int p){
// printf("Pushup(%d,%d,%d)\n",p,tr[p].ls,tr[p].rs);
int pcl=0,pcr=0;
int ls=tr[p].ls,rs=tr[p].rs;
if(tr[p].x){
pcl=0,tr[p].vl=tr[ls].vl;
pcr=1,tr[p].vr=(!tr[rs].cl)?(Init(tr[p].v)+tr[rs].vr):tr[rs].vr;
}
else{
pcr=0,tr[p].vr=tr[rs].vr;
pcl=1,tr[p].vl=(!tr[ls].cr)?(tr[ls].vl+Init(tr[p].v)):tr[ls].vl;
}
tr[p].cr=pcr+max(0,tr[ls].cr-pcl);
tr[p].vl=tr[p].vl+(tr[rs].rst=AskL(rs,tr[p].cr));
tr[p].cr=tr[rs].cr+max(0,tr[p].cr-tr[rs].cl);
tr[p].cl=pcl+max(0,tr[rs].cl-pcr);
tr[p].vr=(tr[ls].rst=AskR(ls,tr[p].cl))+tr[p].vr;
tr[p].cl=tr[ls].cl+max(0,tr[p].cl-tr[ls].cr);
tr[p].siz=tr[ls].siz+tr[rs].siz+1;
// Print(p);
}
void Buildtr(int p){
if(!p) return;
Buildtr(tr[p].ls);
Buildtr(tr[p].rs);
Pushup(p);
}
void Split(int p,int k,int &L,int &R){
if(!p) return L=R=0,void();
if(tr[tr[p].ls].siz>=k){
R=p; Split(tr[p].ls,k,L,tr[p].ls);
Pushup(p);
}
else{
L=p; Split(tr[p].rs,k-tr[tr[p].ls].siz-1,tr[p].rs,R);
Pushup(p);
}
}
int Merge(int p,int q){
if(!p) return q;
if(!q) return p;
if(tr[p].pri>tr[q].pri){
tr[p].rs=Merge(tr[p].rs,q);
Pushup(p); return p;
}
else{
tr[q].ls=Merge(p,tr[q].ls);
Pushup(q); return q;
}
}
void Update(int x,uint y){
int L,M,R;
Split(root,x-1,L,R);
Split(R,1,M,R);
tr[M].x^=1,tr[M].v=y;
if(tr[M].x){
tr[M].cl=0,tr[M].vl=EPT;
tr[M].cr=1,tr[M].vr=Init(tr[M].v);
}
else{
tr[M].cl=1,tr[M].vl=Init(tr[M].v);
tr[M].cr=0,tr[M].vr=EPT;
}
root=Merge(L,Merge(M,R));
}
inline uint Ask(int l,int r){
int L,M,R;
Split(root,r,L,R);
Split(L,l-1,L,M);
Data dat=tr[M].vl+tr[M].vr;
uint res=dat.mx^dat.s1;
root=Merge(L,Merge(M,R));
return res;
}
inline void Swap(int l,int r){
int L,M,R;
Split(root,r,L,R);
Split(L,l-1,L,M);
root=Merge(L,Merge(R,M));
}
signed main(){
// FileIO();
read(n),read(Q);
EPT={0,FUL,0};
tr[0].vl=tr[0].vr=EPT;
for(int i=1;i<=n;i++){
read(a[i]),read(b[i]);
val[i]=i;
tr[i].x=a[i],tr[i].v=b[i];
}
shuffle(val+1,val+n+1,seed);
val[0]=2e9;
stack<int> stk;
stk.push(0);
for(int i=1;i<=n;i++){
int x=0;
while(val[i]>val[stk.top()])
x=stk.top(),stk.pop();
tr[stk.top()].rs=i; tr[i].ls=x;
tr[i].pri=val[i];
if(!stk.top()) root=i;
stk.push(i);
}
Buildtr(root);
// Print(root,"",1);
while(Q--){
int op; read(op);
if(op==1){
int x; uint y;
read(x),read(y);
Update(x,y);
}
else if(op==2){
int l,r;
read(l),read(r);
printf("%u\n",Ask(l,r));
}
else if(op==3){
int l,r;
read(l),read(r);
Swap(l,r);
}
// Print(root,"",1);
}
return 0;
}
Splay:
CPP#include<bits/stdc++.h>
#define ll long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define Ckmax(x,y) x=max(x,y)
#define Ckmin(x,y) x=min(x,y)
#define ull unsigned long long
#define uint unsigned int
using namespace std;
const int N=2e6+5;
const int IINF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3fll;
inline void FileIO(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
}
template<typename Type>
inline void read(Type &res){
Type x=0,f=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
res=x*f;
}
mt19937 seed(time(0));
const uint FUL=0xffffffff;
int n,Q;
int a[N];
uint b[N];
struct Data{
uint s0,s1,mx;
friend Data operator + (Data x,Data y){
return Data{(x.s0&y.s1)|((~x.s0)&y.s0),(x.s1&y.s1)|((~x.s1)&y.s0),max(x.mx,y.mx)};
}
};
#define Init(x) Data{FUL,~(x),(x)}
#define EPT Data{0,FUL,0}
#define likely(x) __builtin_expect(!!(x),1)
struct SplayNode{
int s[2],fa;
int cl,cr;
int x; uint v;
Data vl,vr,rst;
int siz;
#define ls s[0]
#define rs s[1]
}tr[N];
int root,tot;
void Print(int p){
if(!p) puts("EMPTY");
else
printf("Tr[%d]: ls=%d,rs=%d,Bs=(%d,%d),V=(%d,%d),Vl=%u,Vr=%u,Rst=%u,Siz=%d\n",p,tr[p].ls,tr[p].rs,tr[p].cl,tr[p].cr,tr[p].x,tr[p].v,tr[p].vl.s1,tr[p].vr.s1,tr[p].rst.s1,tr[p].siz);
}
void Print(int p,string s,bool fir){
cout<<s<<(fir?"+---":"\\---"); Print(p);
if(!p) return;
s+=(fir?"| ":" ");
Print(tr[p].ls,s,1);
Print(tr[p].rs,s,0);
}
Data AskL(int p,int k){
if(!p||tr[p].cl<=k) return EPT;
if(!k) return tr[p].vl;
Data res=EPT;
while(1){
if(!p||tr[p].cl<=k) break;
if(!k){res=tr[p].vl+res;break;}
int pls=tr[p].ls,prs=tr[p].rs;
int cl=tr[pls].cl+max(0,(!tr[p].x)-tr[pls].cr);
int cr=tr[p].x+max(0,tr[pls].cr-(!tr[p].x));
if(likely(cl<=k)) p=prs,k=k-cl+cr;
else{
res=tr[prs].rst+res;
if(likely(!tr[p].x&&!tr[pls].cr)) res=Init(tr[p].v)+res;
p=pls;
}
}
return res;
}
Data AskR(int p,int k){
if(!p||tr[p].cr<=k) return EPT;
if(!k) return tr[p].vr;
Data res=EPT;
while(1){
if(!p||tr[p].cr<=k) break;
if(!k){res=res+tr[p].vr;break;}
int pls=tr[p].ls,prs=tr[p].rs;
int cl=(!tr[p].x)+max(0,tr[prs].cl-tr[p].x);
int cr=tr[prs].cr+max(0,tr[p].x-tr[prs].cl);
if(likely(cr<=k)) p=pls,k=k-cr+cl;
else{
res=res+tr[pls].rst;
if(likely(tr[p].x&&!tr[prs].cl)) res=res+Init(tr[p].v);
p=prs;
}
}
return res;
}
inline void Pushup(int p){
// printf("Pushup(%d,%d,%d)\n",p,tr[p].ls,tr[p].rs);
int pcl=0,pcr=0;
int pls=tr[p].ls,prs=tr[p].rs;
if(tr[p].x==1){
pcl=0,tr[p].vl=tr[pls].vl;
pcr=1,tr[p].vr=(!tr[prs].cl)?(Init(tr[p].v)+tr[prs].vr):tr[prs].vr;
}
else if(tr[p].x==0){
pcr=0,tr[p].vr=tr[prs].vr;
pcl=1,tr[p].vl=(!tr[pls].cr)?(tr[pls].vl+Init(tr[p].v)):tr[pls].vl;
}
else{
pcl=0,tr[p].vl=tr[pls].vl;
pcr=0,tr[p].vr=tr[prs].vr;
}
tr[p].cr=pcr+max(0,tr[pls].cr-pcl);
tr[p].vl=tr[p].vl+(tr[prs].rst=AskL(prs,tr[p].cr));
tr[p].cr=tr[prs].cr+max(0,tr[p].cr-tr[prs].cl);
tr[p].cl=pcl+max(0,tr[prs].cl-pcr);
tr[p].vr=(tr[pls].rst=AskR(pls,tr[p].cl))+tr[p].vr;
tr[p].cl=tr[pls].cl+max(0,tr[p].cl-tr[pls].cr);
tr[p].siz=tr[pls].siz+tr[prs].siz+1;
// Print(p);
}
void Buildtr(int &p,int l,int r,int pr){
p=++tot; int mid=(l+r)>>1;
tr[p].fa=pr; tr[p].x=a[mid],tr[p].v=b[mid];
if(l!=mid) Buildtr(tr[p].ls,l,mid-1,p);
if(r!=mid) Buildtr(tr[p].rs,mid+1,r,p);
Pushup(p);
}
inline int Dir(int p){return tr[tr[p].fa].rs==p;}
void Rotate(int x){
int y=tr[x].fa,z=tr[y].fa,c=Dir(x);
tr[y].s[c]=tr[x].s[c^1];
if(tr[x].s[c^1]) tr[tr[x].s[c^1]].fa=y;
tr[x].s[c^1]=y; tr[y].fa=x;
tr[x].fa=z;
tr[z].s[y==tr[z].rs]=x;
Pushup(y); Pushup(x);
}
void Splay(int x,int z){
while(tr[x].fa!=z){
int y=tr[x].fa;
if(tr[y].fa!=z)
Rotate(Dir(x)==Dir(y)?y:x);
Rotate(x);
}
if(!z) root=x;
}
int AskNode(int p,int k){
// printf("AskNode(%d)=",k);
while(1){
if(tr[tr[p].ls].siz+1==k) break;
else if(tr[tr[p].ls].siz>=k) p=tr[p].ls;
else k-=tr[tr[p].ls].siz+1,p=tr[p].rs;
}
// printf("%d\n",p);
return p;
}
void Update(int x,uint y){
int p=AskNode(root,x+1);
tr[p].x^=1,tr[p].v=y;
Pushup(p); Splay(p,0);
}
uint Ask(int l,int r){
int p=AskNode(root,l); Splay(p,0);
int q=AskNode(root,r+2); Splay(q,p);
Data res=tr[tr[q].ls].vl+tr[tr[q].ls].vr;
return res.mx^res.s1;
}
void Swap(int l,int r){
if(r==n) return;
int p=AskNode(root,l); Splay(p,0);
int q=AskNode(root,r+2); Splay(q,p);
int z=AskNode(root,n+1);
if(tr[z].rs) Rotate(tr[z].rs);
tr[z].rs=tr[q].ls; tr[q].ls=0;
Pushup(z),Pushup(q);
Splay(z,0);
}
signed main(){
read(n),read(Q);
for(int i=1;i<=n;i++) read(a[i]),read(b[i]);
a[0]=a[n+1]=-1;
tr[0].vl=tr[0].vr=tr[0].rst=EPT;
Buildtr(root,0,n+1,0);
// Print(root,"",1);
while(Q--){
int op; read(op);
if(op==1){
int x; uint y;
read(x),read(y);
Update(x,y);
}
else if(op==2){
int l,r; read(l),read(r);
printf("%u\n",Ask(l,r));
}
else if(op==3){
int l,r; read(l),read(r);
Swap(l,r);
}
// Print(root,"",1);
}
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...