记录编号 449849 评测结果 AAAAAAAAAAA
题目名称 快速红包变换 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 2.380 s
提交时间 2017-09-15 11:06:29 内存使用 13.17 MiB
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
int read(){
	int x=0;bool sign=0;char ch=getchar();
	while ((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
	if (ch=='-') sign=1,ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return sign?-x:x;
}
void print(int x){
	if (!x) return (void)puts("0");
	if (x<0) putchar('-'),x=-x;
	static char str[20]="";
	int len=0;
	for (;x;x/=10) str[++len]=x%10;
	while (len) putchar(str[len--]+'0');
	putchar('\n');
}
const int inf=1e9;
struct pr{int first,second;};
void merge_max(pr &x,pr y){
	if (y.first>x.first) x=y;else
	if (y.first==x.first) x.second+=y.second;
}
void merge_min(pr &x,pr y){
	if (y.first<x.first) x=y;else
	if (y.first==x.first) x.second+=y.second;
}
const int N=1e5+10;
int n,m,a[N],blo[N];
int block_size,num_block;
bool cmp(int x,int y){return a[x]<a[y];}
struct node{
    int val,cnt;
    node *pre,*nxt;
    void init(int Val,int Cnt){val=Val;cnt=Cnt;pre=nxt=0;}
}*Q[N];
struct block_array{
    int l,r,q[1010],pos,tag,sum;
    node *head,*tail;
    void link_to_array(){
        int p=1;
        for (node *i=head;i;i=i->nxt)
            for (int j=0;j<i->cnt;j++) a[q[p++]]=i->val+tag;
    }
    void array_to_link(){
        tag=sum=0;
        for (int i=l;i<=r;i++) sum+=a[i];
        int pt=l;
        (head=tail=Q[pt++])->init(a[q[1]],1);
        for (int i=2;i<=pos;i++)
        if (a[q[i]]==a[q[i-1]]) tail->cnt++;
        else{
            node *p;
            (p=Q[pt++])->init(a[q[i]],1);
            p->pre=tail;
            tail=tail->nxt=p;
        }
    }
    void init(int L,int R){
        l=L;r=min(R,n);
        for (int i=l;i<=r;i++){
            q[++pos]=i;
            blo[i]=num_block;
            Q[i]=new node();
        }
        sort(q+1,q+pos+1,cmp);
        array_to_link();
    }
    int q1[1010],q2[1010],cq1,cq2;
    void rebuild(int L,int R){
        cq1=cq2=0;
        for (int i=1;i<=pos;i++)
            if (L<=q[i]&&q[i]<=R) q1[++cq1]=q[i];
                else q2[++cq2]=q[i];
        pos=0;
        int i=1,j=1;
        while (i<=cq1&&j<=cq2) q[++pos]=(a[q1[i]]<a[q2[j]]?q1[i++]:q2[j++]);
        for (;i<=cq1;q[++pos]=q1[i++]);
        for (;j<=cq2;q[++pos]=q2[j++]);
        array_to_link();
    }
    void makesame(int d){
        (head=tail=Q[l])->init(d,pos);
        tag=0;sum=d*pos;
    }
    void add(int L,int R,int d){
        if (l>=L&&r<=R){tag+=d;sum+=d*pos;return;}
        link_to_array();
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) a[i]+=d;
        rebuild(L,R);
    }
    void makesame(int L,int R,int d){
        if (l>=L&&r<=R) return makesame(d);
        link_to_array();
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) a[i]=d;
        rebuild(L,R);
    }
    void cbmax(int L,int R,int v){
        if (l>=L&&r<=R){
            if (v>=tail->val+tag) return makesame(v);
            if (head->val+tag>=v) return;
            sum+=head->cnt*(v-head->val-tag);
            head->val=v-tag;
            for (node *i=head->nxt;i&&i->val+tag<=v;i=head->nxt=i->nxt){
                sum+=i->cnt*(v-i->val-tag);
                head->cnt+=i->cnt;
            }
            head->nxt->pre=head;
            return;
        }
        link_to_array();
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) a[i]=max(a[i],v);
        rebuild(L,R);
    }
    void cbmin(int L,int R,int v){
        if (l>=L&&r<=R){
            if (v<=head->val+tag) return makesame(v);
            if (tail->val+tag<=v) return;
            sum+=tail->cnt*(v-tail->val-tag);
            tail->val=v-tag;
            for (node *i=tail->pre;i&&i->val+tag>=v;i=tail->pre=i->pre){
                sum+=i->cnt*(v-i->val-tag);
                tail->cnt+=i->cnt;
            }
            tail->pre->nxt=tail;
            return;
        }
        link_to_array();
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) a[i]=min(a[i],v);
        rebuild(L,R);
    }
    int qsum(int L,int R){
        if (l>=L&&r<=R) return sum;
        link_to_array();
        int ans=0;
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) ans+=a[i];
        return ans;
    }
    int qwmax(int L,int R){
        if (l>=L&&r<=R) return tail->val+tag;
        link_to_array();
        int ans=-inf;
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) ans=max(ans,a[i]);
        return ans;
    }
    int qwmin(int L,int R){
        if (l>=L&&r<=R) return head->val+tag;
        link_to_array();
        int ans=inf;
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) ans=min(ans,a[i]);
        return ans;
    }
    pr qnmax(int L,int R){
        if (l>=L&&r<=R) return (pr){tail->val+tag,tail->cnt};
        link_to_array();
        pr ans=(pr){-inf,0};
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) merge_max(ans,(pr){a[i],1});
        return ans;
    }
    pr qnmin(int L,int R){
        if (l>=L&&r<=R) return (pr){head->val+tag,head->cnt};
        link_to_array();
        pr ans=(pr){inf,0};
        L=max(L,l);R=min(R,r);
        for (int i=L;i<=R;i++) merge_min(ans,(pr){a[i],1});
        return ans;
    }
}block[1010];
int main()
{
    freopen("redbag.in","r",stdin);
    freopen("redbag.out","w",stdout);
    scanf("%d",&n);
    block_size=sqrt(n);
    if (block_size<10) block_size=10;
    for (int i=1;i<=n;i++) a[i]=read();
    for (int i=1;i<=n;i+=block_size) block[++num_block].init(i,i+block_size-1);
    scanf("%d",&m);
    char str[10]="";int l,r,v;
    for (int i=1;i<=m;i++){
        scanf("%s",str);l=read();r=read();
        if (str[0]=='C'){
            v=read();
			if (str[1]=='a') for (int i=blo[l];i<=blo[r];i++) block[i].add(l,r,v);else
			if (str[1]=='c') for (int i=blo[l];i<=blo[r];i++) block[i].makesame(l,r,v);else
			if (str[3]=='a') for (int i=blo[l];i<=blo[r];i++) block[i].cbmax(l,r,v);else
			if (str[3]=='i') for (int i=blo[l];i<=blo[r];i++) block[i].cbmin(l,r,v);
        }
        else{
            if (str[1]=='s'){
                int ans=0;
                for (int i=blo[l];i<=blo[r];i++) ans+=block[i].qsum(l,r);
                print(ans);
            }else
            if (str[1]=='w'&&str[3]=='a'){
                int ans=-inf;
                for (int i=blo[l];i<=blo[r];i++) ans=max(ans,block[i].qwmax(l,r));
                print(ans);
            }else
            if (str[1]=='w'&&str[3]=='i'){
                int ans=inf;
                for (int i=blo[l];i<=blo[r];i++) ans=min(ans,block[i].qwmin(l,r));
                print(ans);
            }else
            if (str[1]=='n'&&str[3]=='a'){
                pr ans=(pr){-inf,0};
                for (int i=blo[l];i<=blo[r];i++) merge_max(ans,block[i].qnmax(l,r));
                print(ans.second);
            }else
            if (str[1]=='n'&&str[3]=='i'){
                pr ans=(pr){inf,0};
                for (int i=blo[l];i<=blo[r];i++) merge_min(ans,block[i].qnmin(l,r));
                print(ans.second);
            }
        }
    }
    return 0;
}