首页 > 代码库 > Codeforces679E. Bear and Bad Powers of 42
Codeforces679E. Bear and Bad Powers of 42
传送门
今天子帧的一套模拟题的T3。
考试的时候其实已经想到了正解了,但是一些地方没有想清楚,就没敢写,只打了个暴力。
首先考虑用线段树维护区间信息。
先把每个值拆成两个信息,一是距离他最近的且大于他的$42$的整次幂,而是到距离他最近的且大于他的$42$的整次幂的距离。
操作1和操作2不需要细说。
对于操作3,每次加入一个数后check整棵线段树的Min,如果出现负数就逐个升级。如果出现了0就再次增加,直到不出现0为止。
因为每个数最多升级$logN$次,所以时间上是没有问题的。
另一个小细节(被卡了很长时间),在每次下传操作2的lazytag之前要先将下一个的操作3的lazytag清空。
//Codeforces 679E//by Cydiater//2017.1.20#include <iostream>#include <queue>#include <map>#include <ctime>#include <cstring>#include <string>#include <cmath>#include <ctime>#include <iomanip>#include <cstdlib>#include <cstdio>#include <bitset>#include <set>#include <vector>using namespace std;#define ll long long#define up(i,j,n) for(int i=j;i<=n;i++)#define down(i,j,n) for(int i=j;i>=n;i--)#define cmax(a,b) a=max(a,b)#define cmin(a,b) a=min(a,b)#define FILE "bad42"const int MAXN=2e5+5;inline int read(){ char ch=getchar();int x=0,f=1; while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f;}ll pw[MAXN],N,M,arr[MAXN];//little toolll Level(ll num){up(i,0,11)if(pw[i]>=num)return i;}ll Dist(ll num){up(i,0,11)if(pw[i]>=num)return pw[i]-num;}struct tree{ ll Min,tag1,tag2,level; //tag1 -> opt2 //tag2 -> opt3}t[MAXN<<2];namespace SegmentTree{ inline void reload(int root){t[root].Min=min(t[root<<1].Min,t[root<<1|1].Min);} inline void Uplevel(int root){ ll num=pw[t[root].level]-t[root].Min; t[root].level=Level(num); t[root].Min=Dist(num); } inline void Pushdown(int leftt,int rightt,int root){ if(t[root].tag1>0){ if(leftt!=rightt){ t[root<<1].level=Level(t[root].tag1); t[root<<1].Min=Dist(t[root].tag1); t[root<<1].tag1=t[root].tag1; t[root<<1].tag2=0; t[root<<1|1].level=Level(t[root].tag1); t[root<<1|1].Min=Dist(t[root].tag1); t[root<<1|1].tag1=t[root].tag1; t[root<<1|1].tag2=0; } t[root].tag1=0; } if(t[root].tag2>0){ if(leftt!=rightt){ t[root<<1].Min-=t[root].tag2; t[root<<1].tag2+=t[root].tag2; t[root<<1|1].Min-=t[root].tag2; t[root<<1|1].tag2+=t[root].tag2; } t[root].tag2=0; } } void Build(int leftt,int rightt,int root){ if(leftt==rightt){ t[root].Min=Dist(arr[leftt]);t[root].level=Level(arr[leftt]); t[root].tag1=-1;t[root].tag2=0; return; } int mid=(leftt+rightt)>>1; t[root].tag1=-1;t[root].tag2=0; Build(leftt,mid,root<<1); Build(mid+1,rightt,root<<1|1); reload(root); } ll Realnum(int leftt,int rightt,int root,int pos){ Pushdown(leftt,rightt,root); if(leftt==rightt||t[root].tag1==0) return pw[t[root].level]-t[root].Min; int mid=(leftt+rightt)>>1; if(mid>=pos) return Realnum(leftt,mid,root<<1,pos); else if(mid+1<=pos) return Realnum(mid+1,rightt,root<<1|1,pos); } void Modify(int leftt,int rightt,int root,int L,int R,int val,int tag){ Pushdown(leftt,rightt,root); int mid=(leftt+rightt)>>1; if(leftt>=L&&rightt<=R){ if(tag==1){ t[root].tag1=val; t[root].level=Level(val); t[root].Min=Dist(val); } else{ t[root].tag2=val; t[root].Min-=val; } return; } t[root].tag1=-1; if(L>=mid+1) Modify(mid+1,rightt,root<<1|1,L,R,val,tag); else if(R<=mid) Modify(leftt,mid,root<<1,L,R,val,tag); else{ Modify(leftt,mid,root<<1,L,R,val,tag); Modify(mid+1,rightt,root<<1|1,L,R,val,tag); } reload(root); } void fix(int leftt,int rightt,int root){ Pushdown(leftt,rightt,root); if(leftt==rightt||t[root].tag1==0){ Uplevel(root); return; } int mid=(leftt+rightt)>>1; if(t[root<<1].Min<0) fix(leftt,mid,root<<1); if(t[root<<1|1].Min<0) fix(mid+1,rightt,root<<1|1); reload(root); }}using namespace SegmentTree;namespace solution{ void Prepare(){ pw[0]=1; up(i,1,11)pw[i]=pw[i-1]*42LL; N=read();M=read(); up(i,1,N)arr[i]=read(); Build(1,N,1); } void Solve(){ while(M--){ int opt=read(); if(opt==1){ int pos=read(); printf("%I64d\n",Realnum(1,N,1,pos)); } if(opt==2){ int L=read(),R=read(),val=read(); Modify(1,N,1,L,R,val,1); } if(opt==3){ int L=read(),R=read(),val=read(); do{ Modify(1,N,1,L,R,val,2); //printf("%d\n",Realnum(1,N,1,1)); if(t[1].Min<0)fix(1,N,1); }while(t[1].Min==0); } //up(i,1,N)printf("%d ",Realnum(1,N,1,i));puts(""); } }}int main(){ //freopen("input.in","r",stdin); //freopen("out1.out","w",stdout); //freopen(FILE".in","r",stdin); //freopen(FILE".out","w",stdout); using namespace solution; Prepare(); Solve(); return 0;}
Codeforces679E. Bear and Bad Powers of 42
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。