2 0 1 1 0 3 1 2 2 1 1 2
11 174
按Ai从小到大,Bi从小到大加入,考虑加入的数对答案的影响
b<Bi有cnt个 故
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> #include<vector> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define MEM2(a,i) memset(a,i,sizeof(a)); #define INF (2139062143) #define F (1000000007) #define MAXN (100000+10) #define fi first #define se second #define mp make_pair typedef __int64 ll; ll mul(ll a,ll b){return (a%F*b%F)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} ll pow2(ll a,ll b) { if (b==0) return 1; if (b==1) return a; ll p = pow2(a,b/2); p=p*p%F; if ( b & 1 ) p = p * a%F; return p; } class SegmentTree { ll a[MAXN*4],sumv[MAXN*4],a2[MAXN*4],sumv2[MAXN*4]; int mark[MAXN*4]; int n; public: SegmentTree(){MEM(a) MEM(sumv) MEM(a2) MEM(sumv2) MEM(mark) } SegmentTree(int _n):n(_n){MEM(a) MEM(sumv) MEM(a2) MEM(sumv2) MEM(mark) } void mem(int _n) { n=_n; MEM(a) MEM(sumv) MEM(a2) MEM(sumv2) MEM(mark) } void maintain(int o,int L,int R) { if (L<R) { sumv[o]=(sumv[Lson]+sumv[Rson])%F; sumv2[o]=(sumv2[Lson]+sumv2[Rson])%F; } } int y1,y2; ll v; void update(int o,int L,int R) //y1,y2,v { if (L==R) { sumv[o]++; sumv2[o]=(sumv2[o]+v)%F; return ; } else{ pushdown(o); int M=(R+L)>>1; if (y1<=M) update(Lson,L,M); else update(Rson,M+1,R); } maintain(o,L,R); } void update2(int o,int L,int R) { if (y1<=L&&R<=y2) { mark[o]++;sumv2[o]=(2*sumv2[o])%F; return; } else{ pushdown(o); int M=(R+L)>>1; if (y1<=M) update2(Lson,L,M); if (M< y2) update2(Rson,M+1,R); } maintain(o,L,R); } void pushdown(int o) { if (mark[o]) { mark[Lson]+=mark[o]; mark[Rson]+=mark[o]; ll t=pow2(2,mark[o]); sumv2[Lson]=sumv2[Lson]*t%F; sumv2[Rson]=sumv2[Rson]*t%F; mark[o]=0; } } ll _sum,_sum2; void query2(int o,int L,int R) { if (y1<=L&&R<=y2) { upd(_sum,sumv[o]); upd(_sum2,sumv2[o]); return; } else { pushdown(o); int M=(L+R)>>1; if (y1<=M) query2(Lson,L,M); if (M< y2) query2(Rson,M+1,R); } } void add(int l,ll v) { y1=y2=l;this->v=v; update(1,1,n); } void mul(int l,int r) { if (l>r) return ; y1=l,y2=r; update2(1,1,n); } ll ask(int l,int r,int b=1) { if (l>r) return 0; _sum=_sum2=0; y1=l,y2=r; query2(1,1,n); if (b==1) return _sum; return _sum2; } void print() { For(i,n) cout<<ask(i,i,2)<<' '; cout<<endl; } }S; int n; pair<ll,ll> p[MAXN]; ll bb[MAXN]; int main() { // freopen("hdu4913.in","r",stdin); // freopen(".out","w",stdout); while(scanf("%d",&n)==1) { int a,b; For(i,n) scanf("%d%d",&a,&b),p[i]=mp(a,b),bb[i]=p[i].se; sort(p+1,p+1+n); sort(bb+1,bb+1+n); int m=unique(bb+1,bb+1+n)-(bb+1); S.mem(m); ll ans = 0; For(i,n) { ll a=p[i].fi,b=p[i].se; ll now=pow2(2LL,a),now3=pow2(3LL,b); ll nowv=mul(now,now3); int pos = lower_bound( bb+1 , bb+1+m , p[i].se ) - (bb); ll cnt=S.ask( 1,pos,1); ll tmp=pow2(2,cnt); upd( ans , nowv * tmp % F ); upd( ans , now * S.ask(pos+1,m,2) % F); S.mul(pos+1,m); S.add(pos,mul(now3,tmp)); } printf("%I64d\n",ans%F); } return 0; }