noip模拟34[惨败] (3)

那么如果扩展到多个点的时候,我们只需要根据这两列的点吧整个序列分成几个块就好了

AC_code #include<bits/stdc++.h> using namespace std; #define re register int #define ll long long const int N=1e4+5; const int M=2505; const ll mod=1e9+7; int n; int sca[M][M]; bool vis[M][M]; ll ans; struct BIT{ ll tr[M]; int lb(int x){return x&(-x);} void ins(int x,ll v){ for(re i=x;i<=2500;i+=lb(i)) tr[i]+=v; } ll query(int x){ ll ret=0; for(re i=x;i;i-=lb(i)) ret+=tr[i]; return ret; } }bit[M],num[M]; signed main(){ scanf("%d",&n); for(re i=1;i<=n;i++){ int x,y; scanf("%d%d",&x,&y); sca[x][++sca[x][0]]=y; } for(re i=1;i<=2500;i++){ sca[i][sca[i][0]+1]=2501; sort(sca[i]+1,sca[i]+sca[i][0]+1); } for(re i=1;i<=2500;i++){ if(!sca[i][0])continue; for(re j=1;j<=sca[i][0];j++){ vis[i][sca[i][j]]=true; num[i].ins(sca[i][j],1); bit[i].ins(sca[i][j],sca[i][j]); } for(re j=i-1;j>=1;j--){ if(!sca[j][0])continue; for(re k=1;k<=sca[j][0];k++){ if(vis[i][sca[j][k]])continue; vis[i][sca[j][k]]=true; num[i].ins(sca[j][k],1); bit[i].ins(sca[j][k],sca[j][k]); } int noi=1,noj=1; int upy=max(sca[i][1],sca[j][1]); while(sca[i][noi+1]<=upy)noi++; while(sca[j][noj+1]<=upy)noj++; while(noi<=sca[i][0]&&noj<=sca[j][0]){ int mx=min(sca[i][noi+1],sca[j][noj+1]); int mn=min(sca[i][noi],sca[j][noj]); ll uy=bit[i].query(mx-1)+mod-bit[i].query(upy-1); ll dy=bit[i].query(mn); ll us=num[i].query(mx-1)+mod-num[i].query(upy-1); ll ds=num[i].query(mn); ans=(ans+(uy*ds%mod+mod-dy*us%mod)%mod*(i-j)%mod)%mod; upy=mx; if(sca[i][noi+1]<=mx)noi++; if(sca[j][noj+1]<=mx)noj++; } } } printf("%lld",ans); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwgsfj.html