杭电3 :Photoshop Layers
题面:一张图有n层,m次查询,每一层给出rgb三种数值的16进制,并给出操作数,若为1,则覆盖,为2,则累加,但数值不超过255,每次查询给出l,r层为查询范围,求查询结果。
解析:16进制的存储和应用,因为是三个数值不间断输入,用scanf("%X")存入x中,按位截取又转换成二进制,右移8位则去掉一种数值,这样就可以分别存进b[],g[],r[]中。
每次查询要找到距离r最近的1,再把r,g,b,分别累加。肯定会超时,所以要先进行预处理,详见代码。
代码:
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; int t,n,m,q,ls,rs,temp,x; int r[N],g[N],b[N],f[N]; int ask(int *s,int l,int r){ int ans; int x=f[r]; if(x<l) ans=s[r]-s[l-1];//若区间中不含操作1 else ans=s[r]-s[x-1]; return min(ans,255); } int main(){ scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d%X",&temp,&x); b[i]=x&255; x>>=8; g[i]=x&255; x>>=8; r[i]=x; r[i]+=r[i-1];g[i]+=g[i-1];b[i]+=b[i-1];//只需要前缀和 if(temp==1) f[i]=i; else f[i]=f[i-1]; //存最近的1,在哪层 } for(int i=1;i<=m;i++){ scanf("%d%d",&ls,&rs); printf("%02X%02X%02X\n",ask(r,ls,rs),ask(g,ls,rs),ask(b,ls,rs)); } } }