zoukankan      html  css  js  c++  java
  • 【BZOJ2441】【中山市选2011】小W的问题(树状数组+权值线段树)

    传送门

    由于一个ww不好统计,我们考虑拆成22vv来统计,也就是"312"和"213"这样的
    把答案统计在"2"处,两边相乘就是答案

    由于2种情况类似,只讨论"312"这样的
    考虑对于每个点p(x1,y1)p(x_1,y_1)作为“2”
    那么所有p的左下角的点q(x2,y2)q(x_2,y_2)都可以作为"1"
    在点(x2,y1)(x_2,y_1)左上角的点就都可以作为"3"

    考虑把所有点按照yy排序
    从小到大计算
    然后我们对于每个点维护一个值表示在这个点左上角有多少个所有未被计算的点
    那么对于每个点答案就是左下角所有点的值之和了
    每加一个点就会使右边所有点的值少1,又会新加一个点的值
    考虑到按照yy从小到大计算,可以直接上线段树(以xx坐标为下标)
    统计左上角有多少个点可以直接用树状数组维护

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=200005;
    const ll mod=1000000007;
    int len,n,p[N];
    struct point{
    	int x,y;
    }a[N];
    inline bool comp(const point &a,const point &b){
    	return a.y<b.y;
    }
    ll f[N][2],ans;
    inline void add(ll &a,ll b){
    	a=(a+b>=mod)?a+b-mod:a+b;
    }
    inline void mul(ll &a,ll b){
    	a=(a*b>=mod)?a*b%mod:a*b;
    }
    struct Bit{
    	ll tr[N];
    	inline int lowbit(int x){
    		return (x&(-x));
    	}
    	inline void update(int pos,ll k){
    		for(;pos<=len;pos+=lowbit(pos))add(tr[pos],k);
    	}
    	inline int query(int pos,ll res=0){
    		for(;pos;pos-=lowbit(pos))add(res,tr[pos]);return res;
    	}
    	inline void init(){
    		memset(tr,0,sizeof(tr));
    		for(int i=1;i<=n;i++){
    			int pos=lower_bound(p+1,p+len+1,a[i].x)-p;
    			update(pos,1);
    		}
    	}
    }A;
    struct Seg{
    	#define lc (u<<1)
    	#define rc ((u<<1)|1)
    	#define mid ((l+r)>>1)
    	ll siz[N<<2],tr[N<<2],tag[N<<2];
    	inline void init(){
    		memset(siz,0,sizeof(siz)),memset(tr,0,sizeof(tr)),memset(tag,0,sizeof(tag));
    	}
    	inline void pushup(int u){
    		siz[u]=siz[lc]+siz[rc],tr[u]=tr[lc]+tr[rc];
    	}
    	inline void pushnow(int u,ll k){
    		tr[u]+=k*siz[u],tag[u]+=k;
    	}
    	inline void pushdown(int u){
    		if(!tag[u])return;
    		pushnow(lc,tag[u]),pushnow(rc,tag[u]),tag[u]=0;
    	}
    	inline void update(int u,int l,int r,int st,int des){
    		if(l>des||st>r)return;
    		if(st<=l&&r<=des){
    			pushnow(u,-1);return;
    		}
    		pushdown(u);
    		if(st<=mid)update(lc,l,mid,st,des);
    		if(mid<des)update(rc,mid+1,r,st,des);
    		pushup(u);
    	}
    	inline void modify(int u,int l,int r,int pos,ll k){
    		if(l==r){tr[u]+=k,siz[u]+=1;return;}
    		pushdown(u);
    		if(pos<=mid)modify(lc,l,mid,pos,k);
    		else modify(rc,mid+1,r,pos,k);
    		pushup(u);
    	}
    	inline ll query(int u,int l,int r,int st,int des){
    		if(l>des||r<st)return 0;
    		if(st<=l&&r<=des)return tr[u];
    		pushdown(u);
    		ll res=0;
    		if(st<=mid)res+=query(lc,l,mid,st,des);
    		if(mid<des)res+=query(rc,mid+1,r,st,des);
    		return res;
    	}
    }B;
    int stk[N],top;
    inline void change1(){
    	for(int i=1;i<=top;i++){
    		int pos=lower_bound(p+1,p+len+1,a[stk[i]].x)-p;
    		B.update(1,1,len,pos+1,len),A.update(pos,-1);
    	}
    	for(int i=1;i<=top;i++){
    		int pos=lower_bound(p+1,p+len+1,a[stk[i]].x)-p;
    		f[stk[i]][0]=B.query(1,1,len,1,pos-1);
    	}
    	for(int i=1;i<=top;i++){
    		int pos=lower_bound(p+1,p+len+1,a[stk[i]].x)-p;
    		B.modify(1,1,len,pos,A.query(pos-1));
    	}	
    }
    inline void change2(){
    	for(int i=1;i<=top;i++){
    		int pos=lower_bound(p+1,p+len+1,a[stk[i]].x)-p;
    		B.update(1,1,len,1,pos-1),A.update(pos,-1);
    	}
    	for(int i=1;i<=top;i++){
    		int pos=lower_bound(p+1,p+len+1,a[stk[i]].x)-p;
    		f[stk[i]][1]=B.query(1,1,len,pos+1,len);
    	}
    	for(int i=1;i<=top;i++){
    		int pos=lower_bound(p+1,p+len+1,a[stk[i]].x)-p;
    		B.modify(1,1,len,pos,A.query(len)-A.query(pos));
    	}
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++){
    		p[i]=a[i].x=read(),a[i].y=read();
    	}
    	sort(a+1,a+n+1,comp);
    	sort(p+1,p+n+1),len=unique(p+1,p+n+1)-p-1;
    	A.init(),B.init();
    	for(int i=1;i<=n;i++){
    		stk[top=1]=i;
    		while(i<n&&a[i].y==a[i+1].y)i++,stk[++top]=i;
    		change1();
    	}
    	A.init(),B.init();
    	for(int i=1;i<=n;i++){
    		stk[top=1]=i;
    		while(i<n&&a[i].y==a[i+1].y)i++,stk[++top]=i;
    		change2();
    	}
    	for(int i=1;i<=n;i++)mul(f[i][0],f[i][1]),add(ans,f[i][0]);
    	cout<<ans<<'
    ';
    }
    
  • 相关阅读:
    POJ 2342
    SHU 413
    SHU 414
    进制转换模板
    SHU 第15届上海大学程序设计联赛夏季赛[热身赛] 第三题(G题)
    POJ 3185
    XTU 1260
    高斯消元法模板
    POJ 2057
    模态窗口的定时关闭
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366310.html
Copyright © 2011-2022 走看看