【洛谷八连测R2】fateice-or
题目背景
题目描述
悬浮大陆群边境地带 68号岛,妖精仓库。
在威廉的面前有着数不清的护符,这些护符的功能值从00到2^{30}-1230−1,且每种功能值的护符都可以多次使用。为了调整圣剑,迎战接下来的巨大的六号兽,为了让珂朵莉能够在那场战斗中存活下来,他需要用这些护符重新恢复瑟尼欧尼斯。
这个拼接的过程首先将nn个护符排成一排。
圣剑是由无数护符用咒力线相连,产生复杂的作用之后形成的强大武器。这排护符需要满足全部的mm个条件才能被称为是真正的“瑟尼欧尼斯”。
第ii个条件为将第l_ili个护符的功能值x_{l_i}xli按顺序按位或上第l_i+1,\cdots,r_ili+1,⋯,ri个护符的功能值x_{l_i+1},\cdots,x_{r_i}xli+1,⋯,xri后的结果需为p_ipi。
大战即将来临,珂朵莉能否击败前所未闻的巨大的六号兽,最后平安的回到妖精仓库,取决于您能否快速的完成这个计算了。
《NOIP时在做什么?有没有空?可以来AK吗?》
输入输出格式
输入格式:
第一行两个整数nn,mm。接下来mm行每行三个整数l_ili,r_iri,p_ipi。
输出格式:
如果存在这样的护符序列xx,第一行输出Yes,第二行输出nn个不超过2^{30}-1230−1的非负整数表示x_1,x_2,\cdots,x_nx1,x2,⋯,xn(如果有多种方案,你可以输出任意一种),否则输出一行No。
输入输出样例
2 1 1 2 1
Yes 1 1
说明
对于30%的数据,n,m\leqslant 1000n,m⩽1000。
对于另外30%的数据,p_i \leqslant 1pi⩽1。
对于100%的数据,n,m\leqslant 100000n,m⩽100000,1\leqslant l_i\leqslant r_i\leqslant n1⩽li⩽ri⩽n,0 \leqslant p_i<2^{30}0⩽pi<230。
分析
一题比较裸的线段树。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define lson now<<1,l,mid #define rson now<<1|1,mid+1,r using namespace std; const int maxn=100000+5; inline void read(int &x){ x=0; char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} } int n,m,x,y,p,maxnum=(1<<30)-1,len=1; int f[maxn<<2],tag[maxn<<2],L[maxn],R[maxn],P[maxn]; inline void pushup(int now){ f[now]=f[now<<1]|f[now<<1|1]; } inline void pushdown(int now){ int lc=now<<1,rc=now<<1|1; f[lc]&=f[now]; tag[lc]&=tag[now]; f[rc]&=f[now]; tag[rc]&=tag[now]; tag[now]=maxnum; } void update(int now,int l,int r,int x,int y,int p){ if(x<=l&&r<=y){ f[now]&=p; tag[now]&=p; return; } pushdown(now); int mid=(l+r)>>1; if(x<=mid) update(lson,x,y,p); if(y>mid) update(rson,x,y,p); } int query(int now,int l,int r,int x,int y){ if(x<=l&&r<=y) return f[now]; int res=0,mid=(l+r)>>1; pushdown(now); if(x<=mid) res|=query(lson,x,y); if(y>mid) res|=query(rson,x,y); return res; } int main(){ read(n);read(m); for(;len<n;len<<=1); for(int i=1;i<(len<<1);++i) f[i]=tag[i]=maxnum; for(int i=1;i<=m;++i){ read(L[i]);read(R[i]);read(P[i]); update(1,1,n,L[i],R[i],P[i]); } for(int i=1;i<=m;++i) if(query(1,1,n,L[i],R[i])!=P[i]){ printf("No\n"); return 0; } printf("Yes\n"); for(int i=1;i<=n;++i) printf("%d ",query(1,1,n,i,i)); return 0; }