• bzoj4262: Sum


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4262

    思路:写这题之前推荐先写uoj164

    类似做法的还有HNOI2016序列(我拿莫队水过了)

    也是维护一个函数性质标记

    题解见:http://www.cnblogs.com/clrs97/p/4824806.html


    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    const int maxn=100010,mod=(int)1e9,maxt=maxn<<2,inf=2147483647;
    using namespace std;
    int n,cnt,Q,stk[maxn],top;ll ans[maxn],a[maxn];
    struct quer{int x,l,r,id,op;}q[maxn];
    bool operator <(quer a,quer b){return a.x<b.x;}
    struct data{
    	ll a,b,c,d;
    	void clear(){a=1,b=c=d=0;}
    };
    data operator +(data f,data g){
    	return (data){
    		f.a*g.a,     f.b*g.a+g.b,
    		f.a*g.c+f.c, f.b*g.c+f.d+g.d
    	};
    }
    
    
    void read(int &x){
        char ch;bool ok=0;
        for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
        for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
        if (ok) x=-x;
    }
    
    struct Tsegment{
    	#define ls (p<<1)
    	#define rs (p<<1|1)
    	#define mid ((l+r)>>1)
    	ll len[maxt],v[maxt],s[maxt];data tag[maxt];
    	void update(int p){v[p]=v[ls]+v[rs],s[p]=s[ls]+s[rs];}
    	void addtag(int p,data t){
    		s[p]=t.c*v[p]+t.d*len[p]+s[p];
    		v[p]=t.a*v[p]+t.b*len[p];
    		tag[p]=tag[p]+t;
    	}
    	void down(int p){addtag(ls,tag[p]),addtag(rs,tag[p]),tag[p].clear();}
    	void build(int p,int l,int r){
    		//printf("%d %d %d
    ",p,l,r);
    		tag[p].clear(),len[p]=r-l+1,v[p]=s[p]=0;
    		if (l==r) return;
    		build(ls,l,mid),build(rs,mid+1,r);
    	}
    	void modify(int p,int l,int r,int a,int b,data v){
    		//printf("modify=%d %d %d %d %d
    ",p,l,r,a,b);
    		if (l==a&&r==b){addtag(p,v);return;}
    		down(p);
    		if (b<=mid) modify(ls,l,mid,a,b,v);
    		else if (a>mid) modify(rs,mid+1,r,a,b,v);
    		else modify(ls,l,mid,a,mid,v),modify(rs,mid+1,r,mid+1,b,v);
    		update(p);
    	}
    	void cover(int l,int r,ll v){modify(1,1,n,l,r,(data){0,v,0,0}),addtag(1,(data){1,0,1,0});}
    	ll query(int p,int l,int r,int a,int b){
    		//printf("query=%d %d %d %d %d
    ",p,l,r,a,b);
    		if (l==a&&r==b) return s[p];
    		down(p);
    		if (b<=mid) return query(ls,l,mid,a,b);
    		else if (a>mid) return query(rs,mid+1,r,a,b);
    		else return query(ls,l,mid,a,mid)+query(rs,mid+1,r,mid+1,b);
    	}
    	ll query(int l,int r){return query(1,1,n,l,r);}
    }T;
    
    void work(ll op){
    	T.build(1,1,n),a[0]=inf*op,stk[top=1]=0;
    	//printf("cnt=%d
    ",cnt);
    	for (int i=1,j=1;i<=n;i++){
    		while (top&&a[stk[top]]*op<=a[i]*op) top--;
    		T.cover(stk[top]+1,i,a[i]);stk[++top]=i;
    		for (;q[j].x<i;) j++;
    		for (;q[j].x==i;j++){
    			ans[q[j].id]+=op*T.query(q[j].l,q[j].r)*q[j].op;
    			//printf("%lld
    ",T.query(q[j].l,q[j].r));
    			//printf("end=%d stl=%d str=%d
    ",q[j].x,q[j].l,q[j].r);
    		}
    	}
    }
    
    int main(){
    	scanf("%d",&Q);
    	for (int i=1,l1,l2,r1,r2;i<=Q;i++){
    		read(l1),read(r1),read(l2),read(r2),n=max(max(r1,n),r2);
    		q[++cnt]=(quer){r2,l1,r1,i,1},q[++cnt]=(quer){l2-1,l1,r1,i,-1};
    	}
    	sort(q+1,q+1+cnt);
    	//for (int i=1;i<=cnt;i++) printf("q=x=%d l=%d r=%d
    ",q[i].x,q[i].l,q[i].r);
    	//printf("%d
    ",n);
    	for (int i=1,t1=1023,t2=1025;i<=n;i++,t1=1ll*t1*1023%mod,t2=1ll*t2*1025%mod) a[i]=t1^t2;
    	//for (int i=1;i<=n;i++) printf("%lld
    ",a[i]);
    	work(1),work(-1); 
    	for (int i=1;i<=Q;i++) printf("%lld
    ",ans[i]);
    	return 0;
    }

  • 相关阅读:
    06 | x86架构:有了开放的架构,才能打造开放的营商环境
    02 | 学习路径:爬过这六个陡坡,你就能对Linux了如指掌
    01 | 入学测验:你究竟对Linux操作系统了解多少?
    String、StringBuffer与StringBuilder区别
    JavaSE语言基础之字符串
    JavaSE语言基础之数组及其排序
    JavaSE语言基础之流程控制语句
    JavaSE语言基础之数据类型
    Java开发环境配置
    shell 脚本 自增
  • 原文地址:https://www.cnblogs.com/thythy/p/5493628.html
Copyright © 2020-2023  润新知