记录编号 |
335844 |
评测结果 |
AAAAAAAAAAT |
题目名称 |
快速红包变换 |
最终得分 |
90 |
用户昵称 |
白夜<=>黑天 |
是否通过 |
未通过 |
代码语言 |
C++ |
运行时间 |
3.337 s |
提交时间 |
2016-11-02 19:30:35 |
内存使用 |
12.88 MiB |
显示代码纯文本
- #include<cstdio>
- #include <cstring>
- #define DEFUNC int,int,int,int
- #define a_tree int root,int l,int r
-
- #define mid ((l+r)>>1)
-
- #define this_tree root,l,r
- #define left_tree root<<1,l,mid
- #define right_tree root<<1|1,mid+1,r
-
- #define left_son root<<1
- #define right_son root<<1|1
- const int MAXN=100010;
- const int INF=~0U>>1;
- const char *strc[]={"Cadd","Cchange","Cbmax","Cbmin","Qsum","Qwmax","Qwmin","Qnmax","Qnmin"};
- const int OPT []={ 1, 0, 3, 2, 2, 1, 0, 1, 0};
- const int CDD []={ 0, 0, 0, 0, 0, 0, 0, 1, 1};
- struct NODE{
- int num[2];
- NODE(int x=0,int y=0){num[0]=x;num[1]=y;}
- };
- int w[MAXN];
- bool operator <(NODE a,NODE b){return a.num[0]<b.num[0];}
- NODE min(NODE a,NODE b){return a.num[0]==b.num[0]?NODE(a.num[0],a.num[1]+b.num[1]):a<b?a:b;}
- NODE max(NODE a,NODE b){return a.num[0]==b.num[0]?NODE(a.num[0],a.num[1]+b.num[1]):a<b?b:a;}
- NODE sum(NODE a,NODE b){return NODE(a.num[0]+b.num[0],0);}
- NODE (*cmper[3])(NODE,NODE)={min,max,sum};
- NODE c[MAXN<<2][3];
- void rebuild(int);void push_down(int,int,int);
- void push_set(DEFUNC);void push_sum(DEFUNC);
- void push_max(DEFUNC);void push_min(DEFUNC);
- void (*push[4])(DEFUNC)={push_set,push_sum,push_min,push_max};
- int lazy[MAXN<<2][2];
- int ansl,ansr,number,N_cnt,opt,cdd;
- void push_set(a_tree,int val){
- c[root][0]=
- c[root][1]=NODE(val,r-l+1);
- c[root][2].num[0]=val*(r-l+1);
- lazy[root][1]=0;
- lazy[root][0]=val;
- }
- void push_sum(a_tree,int val){
- c[root][0].num[0]+=val;
- c[root][1].num[0]+=val;
- c[root][2].num[0]+=val*(r-l+1);
- lazy[root][1]+=val;
- }
- void push_min(a_tree,int val){
- if(c[root][1].num[0]<=val)return;
- if(c[root][0].num[0]>=val){
- push_set(this_tree,val);
- return;
- }if(l==r)return;
- push_down(this_tree);
- push_min(left_tree,val);
- push_min(right_tree,val);
- rebuild(root);
- }
- void push_max(a_tree,int val){
- if(c[root][0].num[0]>=val)return;
- if(c[root][1].num[0]<=val){
- push_set(this_tree,val);
- return;
- }if(l==r)return;
- push_down(this_tree);
- push_max(left_tree,val);
- push_max(right_tree,val);
- rebuild(root);
- }
- void rebuild(int root){
- for(int i=0;i<3;++i)
- c[root][i]=cmper[i](c[left_son][i],c[right_son][i]);
- }
- void push_down(a_tree){
- for(int i=0;i<2;++i)
- if(lazy[root][i]!=0){
- push[i](left_tree,lazy[root][i]);
- push[i](right_tree,lazy[root][i]);
- lazy[root][i]=0;
- }
- }
- void build(a_tree){
- if(l==r){
- for(int i=0;i<3;++i)
- c[root][i]=NODE(w[l],1);
- return ;
- }build(left_tree);
- build(right_tree);
- rebuild(root);
- }
- void change(a_tree){
- if(ansl<=l&&r<=ansr){
- push[opt](this_tree,number);
- return;
- }push_down(this_tree);
- if(ansl<=mid)change(left_tree);
- if(ansr> mid)change(right_tree);
- rebuild(root);
- }
- NODE query(a_tree){
- if(ansl<=l&&r<=ansr)
- return c[root][opt];
- push_down(this_tree);rebuild(root);
- if(ansr<=mid)return query(left_tree);
- if(ansl> mid)return query(right_tree);
- return cmper[opt](query(left_tree),query(right_tree));
- }
- int QUERY(int l,int r,int seq){
- ansl=l;ansr=r;opt=OPT[seq];cdd=CDD[seq];
- return query(1,1,N_cnt).num[cdd];
- }
- void CHANGE(int l,int r,int val,int seq){
- ansl=l;ansr=r;number=val;
- opt=OPT[seq];cdd=CDD[seq];
- change(1,1,N_cnt);
- }
- void BUILD(int N){
- N_cnt=N;build(1,1,N_cnt);
- }
- int main(){
- freopen("redbag.in","r",stdin);
- freopen("redbag.out","w",stdout);
- int N,M,x,y,z;
- char sc[7];
- scanf("%d",&N);
- for(int i=1;i<=N;++i)
- scanf("%d",&w[i]);
- BUILD(N);scanf("%d",&M);
- for(int i=1;i<=M;++i){
- scanf("%s",sc);
- for(int j=0;j<9;++j){
- if(strcmp(sc,strc[j])==0){
- if(*sc=='C'){
- scanf("%d%d%d",&x,&y,&z);
- CHANGE(x,y,z,j);
- }else {
- scanf("%d%d",&x,&y);
- printf("%d\n",QUERY(x,y,j));
- }break;
- }
- }
- }
- return 0;
- }