由于一个www不好统计,我们考虑拆成222个vvv来统计,也就是"312"和"213"这样的
把答案统计在"2"处,两边相乘就是答案由于2种情况类似,只讨论"312"这样的
考虑对于每个点p(x1,y1)p(x_1,y_1)p(x1,y1)作为“2” 那么所有p的左下角的点q(x2,y2)q(x_2,y_2)q(x2,y2)都可以作为"1" 在点(x2,y1)(x_2,y_1)(x2,y1)左上角的点就都可以作为"3"考虑把所有点按照yyy排序
从小到大计算 然后我们对于每个点维护一个值表示在这个点左上角有多少个所有未被计算的点 那么对于每个点答案就是左下角所有点的值之和了 每加一个点就会使右边所有点的值少1,又会新加一个点的值 考虑到按照yyy从小到大计算,可以直接上线段树(以xxx坐标为下标) 统计左上角有多少个点可以直接用树状数组维护#includeusing namespace std;#define ll long longinline 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 =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||r