样例已过,WA0求助

P5354 [Ynoi2017] 由乃的 OJ

Dragonest @ 2020-01-26 00:48:32

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const int maxn=100010;
const ll inf=0-1;
struct edge{
    int next,to;
}g[2*maxn];
int head[maxn],cnt;
void add(int from,int to)
{
    g[++cnt].next=head[from];
    g[cnt].to=to;
    head[from]=cnt;
}
ll opt(ll a,int act,ll b)
{
    switch(act){
        case 1:{
            a=(a&b);
            break;
        }
        case 2:{
            a=(a|b);
            break;
        }
        case 3:{
            a=(a^b);
            break;
        }
    }
    return a;
}
int Top[maxn],Size[maxn],id[maxn],zson[maxn];
ll val[maxn],v[maxn];
int sw[maxn],s[maxn];
int dep[maxn],f[maxn];
int num=0;
int n,m,k;
struct node{
    ll f0,f1;
};
struct tree{
    node t[maxn<<3][2];//0?????,1?????
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    void pushup(int p){
        t[p][0].f0=((t[ls(p)][0].f0&t[rs(p)][0].f1)|((~t[ls(p)][0].f0)&t[rs(p)][0].f0));
        t[p][0].f1=((t[ls(p)][0].f1&t[rs(p)][0].f1)|((~t[ls(p)][0].f1)&t[rs(p)][0].f0));
        t[p][1].f0=((t[rs(p)][1].f0&t[ls(p)][1].f1)|((~t[rs(p)][1].f0)&t[ls(p)][1].f0));
        t[p][1].f1=((t[rs(p)][1].f1&t[ls(p)][1].f1)|((~t[rs(p)][1].f1)&t[ls(p)][1].f0));
    }
    void build(int p,int l,int r)
    {
        if(l==r){
            t[p][1].f0=t[p][0].f0=opt(0,sw[l],val[l]);
            t[p][1].f1=t[p][0].f1=opt(inf,sw[l],val[l]);
            return;
        }
        int mid=((l+r)>>1);
        build(ls(p),l,mid);
        build(rs(p),mid+1,r);
        pushup(p);
    }
    void ins(int x,int p,int l,int r,int k,int op)
    {
        if(l==r){
            val[l]=k;
            sw[l]=op;
            t[p][1].f0=t[p][0].f0=opt(0,sw[l],val[l]);
            t[p][1].f1=t[p][0].f1=opt(inf,sw[l],val[l]);
            return;
        }
        int mid=((l+r)>>1);
        if(x<=mid)ins(x,ls(p),l,mid,k,op);
        else ins(x,rs(p),mid+1,r,k,op);
        pushup(p);
    }
    node get_sum(int x,int y,int p,int l,int r,int tow){
        if(x<=l&&y>=r){
            return t[p][tow];
        }
        int mid=((l+r)>>1);
        node r1,r2;
        if(x<=mid)r1=get_sum(x,y,ls(p),l,mid,tow);
        if(y>mid)r2=get_sum(x,y,rs(p),mid+1,r,tow);
        if(x<=mid&&y>mid){
            node ss;
            if(!tow){
                ss.f0=((r1.f0&r2.f1)|((~r1.f0)&r2.f0));
                ss.f1=((r1.f1&r2.f1)|((~r1.f1)&r2.f0));
            }
            else{
                ss.f0=((r2.f0&r1.f1)|((~r2.f0)&r1.f0));
                ss.f1=((r2.f1&r1.f1)|((~r2.f1)&r1.f0));
            }
            return ss;
        }
        else{
            if(x<=mid)return r1;
            else return r2;
        }
    }
    node q_sum(int x,int y)
    {
        node res[2],tmp,ans;
        bool b1=0,b2=0;
        int n1=1,n2=0;
        while(Top[x]!=Top[y]){
            if(dep[Top[x]]<dep[Top[y]]){
                swap(x,y);
                swap(n1,n2);
            }
            tmp=get_sum(id[Top[x]],id[x],1,1,n,n1);
            if(n1){
                if(!b1){
                    res[0]=tmp;
                    b1=1;
                }
                else{
                    res[0].f0=((res[0].f0&tmp.f1)|((~res[0].f0)&tmp.f0));
                    res[0].f1=((res[0].f1&tmp.f1)|((~res[0].f1)&tmp.f0));
                }
            }
            else{
                if(!b2){
                    res[1]=tmp;
                    b2=1;
                }
                else{
                    res[1].f0=((tmp.f0&res[1].f1)|((~tmp.f0)&res[1].f0));
                    res[1].f1=((tmp.f1&res[1].f1)|((~tmp.f1)&res[1].f0));
                }
            }
            x=f[Top[x]];
        }
        if(dep[x]>dep[y]){
            swap(x,y);
        }
        tmp=get_sum(id[x],id[y],1,1,n,);
        if((!b1)&&(!b2))return tmp;
        if(n1){
            if(!b1){
                res[0]=tmp;
                b1=1;
            }
            else{
                res[0].f0=((res[0].f0&tmp.f1)|((~res[0].f0)&tmp.f0));
                res[0].f1=((res[0].f1&tmp.f1)|((~res[0].f1)&tmp.f0));
            }
        }
        else{
            if(!b2){
                res[1]=tmp;
                b2=1;
            }
            else{
                res[1].f0=((tmp.f0&res[1].f1)|((~tmp.f0)&res[1].f0));
                res[1].f1=((tmp.f1&res[1].f1)|((~tmp.f1)&res[1].f0));
            }
        }
        if(!b1)return res[1];
        if(!b2)return res[0];
        ans.f0=((res[0].f0&res[1].f1)|((~res[0].f0)&res[1].f0));
        ans.f1=((res[0].f1&res[1].f1)|((~res[0].f1)&res[1].f0));
        return ans;
    }
}tr;
void dfs1(int x,int fr)
{
    dep[x]=dep[fr]+1;
    f[x]=fr;
    Size[x]=1;
    int _max=0;
    for(int i=head[x];i;i=g[i].next)
    {
        int v=g[i].to;
        if(v==fr)continue;
        dfs1(v,x);
        Size[x]+=Size[v];
        if(Size[v]>_max){
            zson[x]=v;
            _max=Size[v];
        }
    }
}
void dfs2(int x,int fr,int top)
{
    Top[x]=top;
    id[x]=++num;
    sw[num]=s[x];
    val[num]=v[x];
    if(!zson[x])return;
    dfs2(zson[x],x,top);
    for(int i=head[x];i;i=g[i].next){
        int v=g[i].to;
        if(v==fr||v==zson[x])continue;
        dfs2(v,x,v);
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>k;
    int i,j;
    for(i=1;i<=n;i++)
    {
        cin>>s[i]>>v[i];
    }
    for(i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    dfs1(1,0);
    dfs2(1,0,1);
    tr.build(1,1,n);
    while(m--){
        int q,x,y,z;
        cin>>q>>x>>y>>z;
        switch(q){
            case 1:{
                node res=tr.q_sum(x,y);
                ll ans=0,tmp=0;
                for(i=k-1;i>=0;i--){
                    if((res.f0>>i)&1){
                        ans+=(1LL<<i);
                        continue;
                    }
                    if((res.f1>>i)&1){
                        if(tmp+(1LL<<i)<=z){
                            tmp+=(1LL<<i);
                            ans+=(1LL<<i);
                            continue;
                        }
                    }
                }
                printf("%llu\n",ans);
                break;
            }
            case 2:{
                tr.ins(id[x],1,1,n,z,y);
                break;
            }
        }
    }
    return 0;
}

by Dragonest @ 2020-01-26 00:48:59

代码可读性可能较差


by noip @ 2020-01-26 01:35:12

我谔谔


by impuk @ 2020-01-26 09:43:28

惊现lxl!!


by Dragonest @ 2020-01-26 11:46:22

最有可能升天的点是q_sum中当x与y位于同一条链上的拼接处理但是我想不出来怎么改


by Dragonest @ 2020-01-29 00:21:22

换了种写法依然WA0…… 自闭了

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const int maxn=100010;
const ll inf=0-1;
struct edge{
    int next,to;
}g[2*maxn];
int head[maxn],cnt;
void add(int from,int to)
{
    g[++cnt].next=head[from];
    g[cnt].to=to;
    head[from]=cnt;
}
ll opt(ll a,int act,ll b)
{
    switch(act){
        case 1:{
            a=(a&b);
            break;
        }
        case 2:{
            a=(a|b);
            break;
        }
        case 3:{
            a=(a^b);
            break;
        }
    }
    return a;
}
int Top[maxn],Size[maxn],id[maxn],zson[maxn];
ll val[maxn],v[maxn];
int sw[maxn],s[maxn];
int dep[maxn],f[maxn];
int num=0;
int n,m,k;
struct node{
    ll f0,f1;
    ll fx0,fx1;
};
struct tree{
    node t[maxn<<3];//0?????,1?????
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    node update(node l,node r){
        node res;
        res.f0=((l.f0&r.f1)|((~l.f0)&r.f0));
        res.f1=((l.f1&r.f1)|((~l.f1)&r.f0));
        res.fx0=((r.fx0&l.fx1)|((~r.fx0)&l.fx0));
        res.fx1=((r.fx1&l.fx1)|((~r.fx1)&l.fx0));
        return res;
    }
    void pushup(int p){
        t[p]=update(t[ls(p)],t[rs(p)]);
    }
    void build(int p,int l,int r)
    {
        if(l==r){
            t[p].f0=t[p].fx0=opt(0,sw[l],val[l]);
            t[p].f1=t[p].fx1=opt(inf,sw[l],val[l]);
            return;
        }
        int mid=((l+r)>>1);
        build(ls(p),l,mid);
        build(rs(p),mid+1,r);
        pushup(p);
    }
    void ins(int x,int p,int l,int r,int k,int op)
    {
        if(l==r){
            val[l]=k;
            sw[l]=op;
            t[p].f0=t[p].fx0=opt(0,sw[l],val[l]);
            t[p].f1=t[p].fx1=opt(inf,sw[l],val[l]);
            return;
        }
        int mid=((l+r)>>1);
        if(x<=mid)ins(x,ls(p),l,mid,k,op);
        else ins(x,rs(p),mid+1,r,k,op);
        pushup(p);
    }
    node get_sum(int x,int y,int p,int l,int r){
        if(x<=l&&y>=r){
            return t[p];
        }
        int mid=((l+r)>>1);
        node r1,r2;
        if(x<=mid)r1=get_sum(x,y,ls(p),l,mid);
        if(y>mid)r2=get_sum(x,y,rs(p),mid+1,r);
        if(x<=mid&&y>mid){
            node r;
            r=update(r1,r2);
            return r;
        }
        else{
            if(x<=mid)return r1;
            else return r2;
        }
    }
    node ans1[maxn],ans2[maxn];
    int cnt1,cnt2;
    node q_sum(int x,int y)
    {
        cnt1=cnt2=0;
        node ans;
        while(Top[x]!=Top[y]){
            if(dep[Top[x]]<dep[Top[y]]){
                ans1[++cnt1]=get_sum(id[Top[y]],id[y],1,1,n);
                y=f[Top[y]];
            }
            else{
                ans2[++cnt2]=get_sum(id[Top[x]],id[x],1,1,n);
                x=f[Top[x]];
            }
        }
        if(dep[x]>dep[y]){
            swap(x,y);
            ans1[++cnt1]=get_sum(id[x],id[y],1,1,n);
        }
        else ans2[++cnt2]=get_sum(id[x],id[y],1,1,n);
        node r1,r2;
        r1=ans1[cnt1],r2=ans2[1];
        int i;
        for(i=cnt1-1;i>0;i--)r1=update(r1,ans1[i]);
        for(i=2;i<=cnt2;i++)r2=update(ans2[i],r2);
        if(cnt2==0)return r1;
        if(cnt1==0)return r2;
        ans.f0=((r2.fx0&r1.f1)|((~r2.fx0)&r1.f0));
        ans.f1=((r2.fx1&r1.f1)|((~r2.fx1)&r1.f0));
        return ans;
    }
}tr;
void dfs1(int x,int fr)
{
    dep[x]=dep[fr]+1;
    f[x]=fr;
    Size[x]=1;
    int _max=0;
    for(int i=head[x];i;i=g[i].next)
    {
        int v=g[i].to;
        if(v==fr)continue;
        dfs1(v,x);
        Size[x]+=Size[v];
        if(Size[v]>_max){
            zson[x]=v;
            _max=Size[v];
        }
    }
}
void dfs2(int x,int fr,int top)
{
    Top[x]=top;
    id[x]=++num;
    sw[num]=s[x];
    val[num]=v[x];
    if(!zson[x])return;
    dfs2(zson[x],x,top);
    for(int i=head[x];i;i=g[i].next){
        int v=g[i].to;
        if(v==fr||v==zson[x])continue;
        dfs2(v,x,v);
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>k;
    int i,j;
    for(i=1;i<=n;i++)
    {
        cin>>s[i]>>v[i];
    }
    for(i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    dfs1(1,0);
    dfs2(1,0,1);
    tr.build(1,1,n);
    while(m--){
        int q,x,y,z;
        cin>>q>>x>>y>>z;
        switch(q){
            case 1:{
                node res=tr.q_sum(x,y);
                ll ans=0,tmp=0;
                for(i=k-1;i>=0;i--){
                    if((res.f0>>i)&1){
                        ans+=(1LL<<i);
                        continue;
                    }
                    if((res.f1>>i)&1){
                        if(tmp+(1LL<<i)<=z){
                            tmp+=(1LL<<i);
                            ans+=(1LL<<i);
                            continue;
                        }
                    }
                }
                cout<<ans<<endl;
                break;
            }
            case 2:{
                tr.ins(id[x],1,1,n,z,y);
                break;
            }
        }
    }
    return 0;
}

by Dragonest @ 2020-01-29 00:44:07

注:靠全开ull捞到40分。


by Dragonest @ 2020-01-29 02:30:22

已通过,AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
const int maxn=100010;
const ll inf=0-1;
struct edge{
    int next,to;
}g[2*maxn];
int head[maxn],cnt;
void add(int from,int to)
{
    g[++cnt].next=head[from];
    g[cnt].to=to;
    head[from]=cnt;
}
ll opt(ll a,int act,ll b)
{
    switch(act){
        case 1:{
            a=(a&b);
            break;
        }
        case 2:{
            a=(a|b);
            break;
        }
        case 3:{
            a=(a^b);
            break;
        }
    }
    return a;
}
int Top[maxn],Size[maxn],id[maxn],zson[maxn];
ll val[maxn],v[maxn];
int sw[maxn],s[maxn];
int dep[maxn],f[maxn];
int num=0;
int n,m,k;
struct node{
    ll f0,f1;
    ll fx0,fx1;
};
struct tree{
    node t[maxn<<3];//0?????,1?????
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    node update(node l,node r){
        node res;
        res.f0=((l.f0&r.f1)|((~l.f0)&r.f0));
        res.f1=((l.f1&r.f1)|((~l.f1)&r.f0));
        res.fx0=((r.fx0&l.fx1)|((~r.fx0)&l.fx0));
        res.fx1=((r.fx1&l.fx1)|((~r.fx1)&l.fx0));
        return res;
    }
    void pushup(int p){
        t[p]=update(t[ls(p)],t[rs(p)]);
    }
    void build(int p,int l,int r)
    {
        if(l==r){
            t[p].f0=t[p].fx0=opt(0,sw[l],val[l]);
            t[p].f1=t[p].fx1=opt(inf,sw[l],val[l]);
            return;
        }
        int mid=((l+r)>>1);
        build(ls(p),l,mid);
        build(rs(p),mid+1,r);
        pushup(p);
    }
    void ins(int x,int p,int l,int r,ll k,ll op)
    {
        if(l==r){
            val[l]=k;
            sw[l]=op;
            t[p].f0=t[p].fx0=opt(0,sw[l],val[l]);
            t[p].f1=t[p].fx1=opt(inf,sw[l],val[l]);
            return;
        }
        int mid=((l+r)>>1);
        if(x<=mid)ins(x,ls(p),l,mid,k,op);
        else ins(x,rs(p),mid+1,r,k,op);
        pushup(p);
    }
    node get_sum(int x,int y,int p,int l,int r){
        if(x<=l&&y>=r){
            return t[p];
        }
        int mid=((l+r)>>1);
        node r1,r2;
        if(x<=mid)r1=get_sum(x,y,ls(p),l,mid);
        if(y>mid)r2=get_sum(x,y,rs(p),mid+1,r);
        if(x<=mid&&y>mid){
            node r;
            r=update(r1,r2);
            return r;
        }
        else{
            if(x<=mid)return r1;
            else return r2;
        }
    }
    node ans1[maxn],ans2[maxn];
    int cnt1,cnt2;
    node q_sum(int x,int y)
    {
        cnt1=cnt2=0;
        node ans;
        while(Top[x]!=Top[y]){
            if(dep[Top[x]]<dep[Top[y]]){
                ans1[++cnt1]=get_sum(id[Top[y]],id[y],1,1,n);
                y=f[Top[y]];
            }
            else{
                ans2[++cnt2]=get_sum(id[Top[x]],id[x],1,1,n);
                x=f[Top[x]];
            }
        }
        if(dep[x]>dep[y]){
            swap(x,y);
            ans2[++cnt2]=get_sum(id[x],id[y],1,1,n);
        }
        else ans1[++cnt1]=get_sum(id[x],id[y],1,1,n);
        node r1,r2;
        r1=ans1[cnt1],r2=ans2[1];
        int i;
        for(i=cnt1-1;i>0;i--)r1=update(r1,ans1[i]);
        for(i=2;i<=cnt2;i++)r2=update(ans2[i],r2);
        if(cnt2==0)return r1;
        if(cnt1==0){
            swap(r2.f0,r2.fx0);
            swap(r2.f1,r2.fx1);
            return r2;
        }
        ans.f0=((r2.fx0&r1.f1)|((~r2.fx0)&r1.f0));
        ans.f1=((r2.fx1&r1.f1)|((~r2.fx1)&r1.f0));
        return ans;
    }
}tr;
void dfs1(int x,int fr)
{
    dep[x]=dep[fr]+1;
    f[x]=fr;
    Size[x]=1;
    int _max=0;
    for(int i=head[x];i;i=g[i].next)
    {
        int v=g[i].to;
        if(v==fr)continue;
        dfs1(v,x);
        Size[x]+=Size[v];
        if(Size[v]>_max){
            zson[x]=v;
            _max=Size[v];
        }
    }
}
void dfs2(int x,int fr,int top)
{
    Top[x]=top;
    id[x]=++num;
    sw[num]=s[x];
    val[num]=v[x];
    if(!zson[x])return;
    dfs2(zson[x],x,top);
    for(int i=head[x];i;i=g[i].next){
        int v=g[i].to;
        if(v==fr||v==zson[x])continue;
        dfs2(v,x,v);
    }
}
int main()
{
    // freopen("test.in","r",stdin);
    // freopen("my.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>k;
    int i,j;
    for(i=1;i<=n;i++)
    {
        cin>>s[i]>>v[i];
    }
    for(i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    dfs1(1,0);
    dfs2(1,0,1);
    tr.build(1,1,n);
    ll sb=1;
    while(m--){
        ll q,x,y,z;
        cin>>q>>x>>y>>z;
        switch(q){
            case 1:{
                node res=tr.q_sum(x,y);
                ll ans=0,tmp=0;
                for(i=63;i>=0;i--){
                    if((res.f0>>i)&1ull){
                        ans+=(1ull<<i);
                        continue;
                    }
                    if((res.f1>>i)&1ull){
                        if(tmp+(1ull<<i)<=z){
                            tmp+=(1ull<<i);
                            ans+=(1ull<<i);
                            continue;
                        }
                    }
                }
                cout<<ans<<endl;
                break;
            }
            case 2:{
                tr.ins(id[x],1,1,n,z,y);
                break;
            }
        }
    }
    return 0;
}

错误全在q_sum中。 我真是个渣渣


by Spasmodic @ 2020-03-13 10:42:27

%%%


by 风之影音 @ 2020-03-26 14:32:30

永远不要怀疑洛谷的评测机


|