BZOJ 4811: [Ynoi2017]由乃的OJ

16人阅读 评论(0) 收藏 举报
分类:

辣鸡csdn要我改密码所以发晚了

老年选手懒于写blog(躺

反正也步入晚年,准备AFO

这道题不错 想写写

其实 O(nklog2) 的做法并不难想到,我们只要枚举某一位填了0或1结果会是啥就行了

剩下就是树剖的操作了

然而其实每一位是不必枚举的,在线段树中,你只要维护全部是0或者全部是1的就可以了

v0[u]=(v0[l]&v1[r])|(~v0[l]&v0[r]);
v1[u]=(v1[l]&v1[r])|(~v1[l]&v0[r]);

因为是沿着路径走的,所以线段树也要维护从区间从右往左的这个东西,跟上面道理差不多

.最后每一位贪心取一下,保证一下不超约束就好。

我觉得我有点蛋疼,一开始为了短线段树打了数组,后面合并就有点蛋疼了…

后来发现写结构体的话似乎方便多了、

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const int N=1e5+2,inf=1e9+7;
char O[1<<14],*S=O,*T=O;
#define gc (S==T&&(T=(S=O)+fread(O,1,1<<14,stdin),S==T)?-1:*S++)
inline LL read(){
    LL x=0,f=1; char ch=gc;
    while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=gc;}
    while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=gc;}
    return x*f;
}
struct E{int y,nex;}e[N<<1];
int len,fir[N],tot,cnt,q,lc[N*3],rc[N*3],n;
LL v0[N*3],v1[N*3],w0[N*3],w1[N*3],a[N],mx;
void ins(int x,int y){
    e[++len]=(E){y,fir[x]},fir[x]=len;
}
int id,p[N],dfn[N],sz[N],son[N],dep[N],fa[N],top[N],o[N];
void dfs(int x){
    sz[x]=1;
    for(int k=fir[x];k;k=e[k].nex){
        int y=e[k].y; if(y==fa[x])continue;
        fa[y]=x,dep[y]=dep[x]+1,dfs(y); sz[x]+=sz[y];
        if(sz[y]>sz[son[x]]) son[x]=y;
    }
}
void dfs1(int x,int tp){
    dfn[x]=++id,o[id]=x,top[x]=tp;
    if(!son[x])return;
    dfs1(son[x],tp);
    for(int k=fir[x];k;k=e[k].nex)
        if(e[k].y!=fa[x] && e[k].y!=son[x]) dfs1(e[k].y,e[k].y);
}
inline LL cal(LL x,int u){
    if(p[u]==1) return x&a[u];
    if(p[u]==2) return x|a[u];
    return x^a[u];
}
void upd(int x,int l,int r){
    int u=tot+1;
    v0[u]=(v0[l]&v1[r])|(~v0[l]&v0[r]);
    v1[u]=(v1[l]&v1[r])|(~v1[l]&v0[r]);
    w0[u]=(w0[r]&w1[l])|(~w0[r]&w0[l]);
    w1[u]=(w1[r]&w1[l])|(~w1[r]&w0[l]);
    v0[x]=v0[u],v1[x]=v1[u],w0[x]=w0[u],w1[x]=w1[u];
}
void bt(int &x,int l,int r){
    x=++tot; int mid=l+r>>1;
    if(l==r){
        int u=o[l];
        v0[x]=w0[x]=cal(0,u),v1[x]=w1[x]=cal(mx,u);
        return;
    }
    bt(lc[x],l,mid),bt(rc[x],mid+1,r);
    upd(x,lc[x],rc[x]);
}
void cha(int x,int l,int r,int k){
    if(l==r){
        int u=o[l];
        v0[x]=w0[x]=cal(0,u),v1[x]=w1[x]=cal(mx,u);
        return;
    }
    int mid=l+r>>1;
    if(k<=mid) cha(lc[x],l,mid,k);
    else cha(rc[x],mid+1,r,k);
    upd(x,lc[x],rc[x]);
}
int get(int x,int l,int r,int ql,int qr){
    if(l==ql && r==qr) return x;
    int mid=l+r>>1;
    if(ql>mid) return get(rc[x],mid+1,r,ql,qr);
    if(qr<=mid) return get(lc[x],l,mid,ql,qr);
    int u=++tot;
    upd(u,get(lc[x],l,mid,ql,mid),get(rc[x],mid+1,r,mid+1,qr));
    return u;
}
int turn(int x){
    int u=x; if(u<=cnt) u=tot+2;
    v0[u]=v0[x],v1[u]=v1[x],w0[u]=w0[x],w1[u]=w1[x];
    swap(v0[u],w0[u]),swap(v1[u],w1[u]);
    return u;
}
void solve(int x,int y){
    int vx=++tot,vy=++tot;
    v0[vx]=v0[vy]=w0[vx]=w0[vy]=0;
    v1[vx]=v1[vy]=w1[vx]=w1[vy]=mx;
    int fx=top[x],fy=top[y];
    while(fx!=fy)
        if(dep[fx]>dep[fy]) upd(vx,vx,turn( get(1,1,n,dfn[fx],dfn[x]) )),x=fa[fx],fx=top[x];
        else upd(vy,get(1,1,n,dfn[fy],dfn[y]),vy),y=fa[fy],fy=top[y];
    if(dep[x]>dep[y]) upd(vx,vx,turn( get(1,1,n,dfn[y],dfn[x]) ));
    else upd(vx,vx,get(1,1,n,dfn[x],dfn[y]));
    upd(q,vx,vy);
}
int main(){
    n=read(); int m=read(),Z=read();
    for(int i=1;i<=n;++i) p[i]=read(),a[i]=read();
    for(int i=1,x,y;i<n;++i) x=read(),y=read(),ins(x,y),ins(y,x);
    dfs(1); dfs1(1,1);
    mx=0ull-1; bt(cnt,1,n); cnt=tot;
    while(m--){
        int u=read(); LL x=read(),y=read(),z=read();
        if(u==2) a[x]=z,p[x]=y,cha(1,1,n,dfn[x]);
        else{
            q=++tot; solve(x,y); LL ans=0,now=0;
            for(int i=Z-1;~i;--i)
                if(v0[q]&(1ull<<i)) ans+=1ull<<i;
                else if(v1[q]&(1ull<<i) && now+(1ull<<i)<=z) now+=1ull<<i,ans+=1ull<<i;
            printf("%llu\n",ans);
            tot=cnt;
        }
    }
    return 0;
}
查看评论

bzoj 4811: [Ynoi2017]由乃的OJ (树链剖分)

题目描述传送门题解这道题与Noi2014起床困难综合症 十分类似。同样的每一位也是互补影响的,那么最基础的思路就是对于每一位分开维护,对于树进行树链剖分,对于线段树中的区间维护以0,1打头从左到右和从...
  • clover_hxy
  • clover_hxy
  • 2017-04-16 09:49:43
  • 445

BZOJ4811 [Ynoi2017]由乃的OJ

显然用LCT维护一下经过一条链之后每一位原来是1会变成什么原来是0会变成什么即可 这样的话LCT复杂度是n log n * k的,链剖是n log^2 n * k的,都过不了 考虑把这个k给去掉,...
  • neither_nor
  • neither_nor
  • 2017-04-07 15:04:09
  • 1031

BZOJ4811: [Ynoi2017]由乃的OJ 重链剖分

题意:起床困难综合征出到树上,带单点修改和区间询问 很容易想到在线段树上维护每一位遍历所有操作后会变成什么,但是第一次交TLE了。。。 然后发现我以前是不是写了假的《又是nand》。。。我说怎么跑...
  • Mima_Reincarnation
  • Mima_Reincarnation
  • 2017-04-11 16:57:34
  • 821

BZOJ 4811([Ynoi2017]由乃的OJ-树链剖分)

Description由乃正在做她的OJ。现在她在处理OJ上的用户排名问题。OJ上注册了n个用户,编号为1~”,一开始他们按照编号 排名。由乃会按照心情对这些用户做以下四种操作,修改用户的排名和编号...
  • nike0good
  • nike0good
  • 2017-04-29 19:06:32
  • 496

[莫队 分块] BZOJ 4866 [Ynoi2017]由乃的商场之旅

这个 只会莫队乱搞 自己YY下 复杂度O(n26∗n−−−−−√)O(n\sqrt{26*n}) 成功贴时限过加时间垫底#include #include #include #include us...
  • u014609452
  • u014609452
  • 2017-04-24 20:58:41
  • 692

[bzoj4867] [Ynoi2017]舌尖上的由乃

题目大意给定一棵n个节点的树,边有边权。m个操作:1. 给一条边边权加k;2.询问一棵子树第k小的深度。 修改操作的k和最初的边权不超过一个给定的常数lenn,m≤100000 len≤10分析...
  • WorldWide_D
  • WorldWide_D
  • 2017-09-02 22:13:20
  • 340

[分块] BZOJ 4867 [Ynoi2017]舌尖上的由乃

这个题啊 分块 每块O(n√)O(\sqrt n) 把每个块内出现次数做一个前缀和,方便二分的时候O(1)查 然后整块加就打标记,两边零散的,变化不超过10,那么就直接在前缀和数组上修改下 复杂...
  • u014609452
  • u014609452
  • 2017-06-17 18:42:07
  • 483

BZOJ4810 [Ynoi2017]由乃的玉米田

对每个区间维护一下这个区间每个数有没有,用bitset压一下,这个用莫队跑出来,然后就能判加减合不合法了 乘的话根号枚举一下就行了 #include #include #include #incl...
  • neither_nor
  • neither_nor
  • 2017-04-07 11:35:57
  • 977

bzoj 4866: [Ynoi2017]由乃的商场之旅 莫队算法

题意给出一个长度为n的由小写字母组成的字符串,每次询问一个区间内有多少连续子串重新排列后可以得到一个回文串。 n,q...
  • qq_33229466
  • qq_33229466
  • 2017-04-26 19:40:33
  • 505

bzoj4810 [Ynoi2017]由乃的玉米田 莫队+bitset

Description由乃在自己的农田边散步,她突然发现田里的一排玉米非常的不美。这排玉米一共有N株,它们的高度参差不齐。 由乃认为玉米田不美,所以她决定出个数据结构题这个题是这样的: 给你一个序...
  • qq_35866453
  • qq_35866453
  • 2017-04-18 21:03:12
  • 295
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 5万+
    积分: 2442
    排名: 1万+