• [PKUSC2021]代金券


    考场上这题我严重降智只拿了(11 pts)。。
    感觉自己思维能力和猜结论的能力应当加强,不应该在无关紧要的地方浪费时间。
    这题切的人好像不少的样子。。他们太强了
    发现总是存在一个(i in [1,n]) 满足(>i)的部分应该全部用优惠券支付,(<i)的部分在保证优惠券数量最大的前提下最大化使用的数量。
    (即对于(j<i)使用的优惠券不应超过(a_j mod C)
    (i)使用的优惠券个数可以二分出来。
    而且可以发现这个(i)总是取优惠券数目足够的前提下的最大的(i)
    这个可以用线段树维护,我的方法是维护((a,b))表示剩下(a)个优惠券,还可以使用(b)个优惠券。

    #include<bits/stdc++.h>
    using namespace std;
    #define fp(i,l,r) for(register int (i)=(l);i<=(r);++(i))
    #define fd(i,l,r) for(register int (i)=(l);i>=(r);--(i))
    #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next)
    #define mem(a) memset((a),0,sizeof (a)) 
    #define O(x) cerr<<#x<<':'<<x<<endl
    #define int long long
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    void wr(int x){
    	if(x<0)x=-x,putchar('-');
    	if(x>=10)wr(x/10);
    	putchar('0'+x%10);
    }
    const int MAXN=3e5+10;
    int n,Q,C,a[MAXN],b[MAXN],c[MAXN];
    struct node{
    	int a,b;
    	inline node operator+(const node &s)const{
    		int t=min(a,s.b);
    		return {a+s.a-t,b+s.b-t};
    	}
    }tr[MAXN<<2];
    int sum[MAXN<<2];
    #define lson o<<1
    #define rson o<<1|1
    inline void pushup(int o){
    	sum[o]=sum[lson]+sum[rson];
    	tr[o]=tr[lson]+tr[rson];
    }
    void build(int o,int l,int r){
    	if(l==r){
    		tr[o]={a[l],b[l]};sum[o]=c[l];
    		return;
    	}
    	int mid=l+r>>1;
    	build(lson,l,mid);build(rson,mid+1,r);
    	pushup(o);
    }
    int num,p;node tar;
    void ask(int o,int l,int r,node t,int s){
    	if(l==r){
    		if(t.a+a[l]<s)return;
    		p=l;num=s;tar=t;
    		return;
    	}
    	int mid=l+r>>1,rsv=s+sum[rson]-c[mid+1];node lsv=t+tr[lson];
    	if(lsv.a+a[mid+1]<rsv)ask(rson,mid+1,r,lsv,s);
    	else p=mid+1,num=rsv,tar=lsv,ask(lson,l,mid,t,s+sum[rson]);
    }
    void upd(int o,int l,int r,int p){
    	if(l==r){
    		tr[o]={a[l],b[l]};sum[o]=c[l];
    		return;
    	}
    	int mid=l+r>>1;
    	if(p<=mid)upd(lson,l,mid,p);
    	else upd(rson,mid+1,r,p);
    	pushup(o);
    }
    struct BIT{
    	int c[MAXN];
    	inline void add(int i,int v){
    		for(;i<=n;i+=i&-i)c[i]+=v;
    	}
    	inline int ask(int i){
    		int res=0;
    		for(;i;i-=i&-i)res+=c[i];
    		return res;
    	}
    }T;
    inline void solve(){
    	ask(1,1,n,{0,0},0);int lim=min({c[p],tar.a,(C*(tar.a-num)+c[p])/(C+1)});
    	/*int l=0,r=min(c[p],tar.a),res;
    	while(l<=r){
    		int mid=l+r>>1;
    		if(tar.a-mid+(c[p]-mid)/C>=num)res=mid,l=mid+1;
    		else r=mid-1;
    	}
    	assert(lim==res);*/
    	wr(tar.b+c[p]-lim+T.ask(p-1));putchar('
    ');
    }
    main(){
    	n=read();Q=read();C=read();
    	fp(i,1,n){
    		c[i]=read();
    		b[i]=c[i]%C;a[i]=c[i]/C;T.add(i,c[i]-b[i]);
    	}
    	build(1,1,n);solve();
    	while(Q--){
    		int p=read(),cp=read();
    		int bp=cp%C,ap=cp/C;T.add(p,-c[p]+b[p]+cp-bp);
    		a[p]=ap;b[p]=bp;c[p]=cp;upd(1,1,n,p);solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    三种常用的迭代搜索优化方法
    三种常用的迭代搜索优化方法
    颜色空间总结
    颜色空间总结
    卷积神经网络(CNN)
    卷积神经网络(CNN)
    在沉睡中站立起来
    在沉睡中站立起来
    Terence’s Stuff: Why do we do research?
    Terence’s Stuff: Why do we do research?
  • 原文地址:https://www.cnblogs.com/WinterSpell/p/14781200.html
Copyright © 2020-2023  润新知