Contest
时间限制:1秒 空间限制:131072K
题目描述
n支队伍一共参加了三场比赛。
一支队伍x认为自己比另一支队伍y强当且仅当x在至少一场比赛中比y的排名高。
求有多少组(x,y),使得x自己觉得比y强,y自己也觉得比x强。
(x, y), (y, x)算一组。
输入描述:
第一行一个整数n,表示队伍数; 接下来n行,每行三个整数a[i], b[i], c[i],分别表示i在第一场、第二场和第三场比赛中的名次;n 最大不超过200000
输出描述:
输出一个整数表示满足条件的(x,y)数;64bit请用lld
示例1
输入
4 1 3 1 2 2 4 4 1 2 3 4 3
输出
5
求三维偏序对,在二维的基础上可以进行,这个可以BIT+CDQ啊,但是超时妥妥的
超时代码
#include<stdio.h> #include<bits/stdc++.h> using namespace std; #define maxn 200002 typedef long long ll; int T,n,tot,id[maxn]; inline char _getchar() { static const int BUFSIZE = 100001 ; static char buf[BUFSIZE] ; static char *psta=buf, *pend=buf ; if (psta >= pend){ psta = buf; pend = buf + fread(buf,1,BUFSIZE,stdin); if (psta >= pend) return -1; } return *psta++; } inline void read(int &x) { char c; int ans=0; for(c=getchar(); c<'0'||c>'9'; c=getchar()); while(c>='0'&&c<='9') ans=(ans<<1)+(ans<<3)+(c-'0'),c=getchar(); x=ans; } struct node { int x,y,z,cnt,ans,id; } p[maxn]; int cmpx(node a,node b) { if(a.x!=b.x)return a.x<b.x; if(a.y!=b.y)return a.y<b.y; return a.z<b.z; } int cmpy(node a,node b) { if(a.y!=b.y)return a.y<b.y; return a.z<b.z; } int cmpid(node a,node b) { return a.id<b.id; } struct BIT { #define lowbit(x) (x&(-x)) int b[maxn]; void init() { memset(b,0,sizeof(b)); } void update(int x,int v) { while(x<=maxn) { b[x]+=v; x+=lowbit(x); } } int query(int x) { int ans=0; while(x) { ans+=b[x]; x-=lowbit(x); } return ans; } void clear(int x) { while(x<=maxn) { b[x]=0; x+=lowbit(x); } } } bit; void CDQ(int l,int r) { if(l==r) { p[l].ans+=p[l].cnt-1; return ; } int mid=(l+r)>>1; CDQ(l,mid); CDQ(mid+1,r); sort(p+l,p+mid+1,cmpy); sort(p+mid+1,p+r+1,cmpy); int j=l; for(int i=mid+1; i<=r; i++) { for(; j<=mid&&p[j].y<=p[i].y; j++) bit.update(p[j].z,p[j].cnt); p[i].ans+=bit.query(p[i].z); } for(int i=l; i<j; i++)bit.update(p[i].z,-p[i].cnt); sort(p+l,p+r+1,cmpy); } int main() { read(n); bit.init(); tot=0; for(int i=1; i<=n; i++) { read(p[i].x); read(p[i].y); read(p[i].z); p[i].ans=0,p[i].id=i; } sort(p+1,p+n+1,cmpx); for(int i=1; i<=n; i++) { if(i!=1&&p[i-1].x==p[i].x&&p[i-1].y==p[i].y&&p[i-1].z==p[i].z) p[tot].cnt++; else p[++tot]=p[i],p[tot].cnt=1; id[p[i].id]=tot; p[tot].id=tot; } CDQ(1,tot); sort(p+1,p+tot+1,cmpid); ll ans=1ll*n*(n-1)/2; for(int i=1; i<=n; i++) ans-=p[id[i]].ans; printf("%lld",ans); return 0; }
为什么要CDQ啊,严重拖慢了时间啊,但是扔到CF上是可以AC的,谁让CF的机器跑的快呢
附上AC代码
#include<bits/stdc++.h> using namespace std; #define LL long long const int maxn=200005; const int K = 450; struct Point { int x,y,z; bool operator < (const Point& rhs) const {return z<rhs.z;} }p[maxn]; int n,c[maxn/K+5][maxn/K+5]; inline int lowbit(int x) {return x&(-x);} int query2D(int qx,int qy) { int ret=0; while(qy) { ret+=c[qx][qy]; qy-=lowbit(qy); } return ret; } int query1D(int qx,int qy) { int ret=0; while(qx) { ret+=query2D(qx,qy); qx-=lowbit(qx); } return ret; } void modify2D(int px,int py,int v) { while(py<=(n/K)) { c[px][py]+=v; py+=lowbit(py); } } void modify1D(int px,int py,int v) { while(px<=(n/K)) { modify2D(px,py,v); px+=lowbit(px); } } int X[maxn],Y[maxn]; int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].z); for(int i=0;i<=n;i++) X[i]=n+1,Y[i]=n+1; sort(p,p+n); LL ans=(LL)n*(n-1)/2LL; for(int i=0;i<n;i++) { ans-=query1D(p[i].x/K,p[i].y/K); for(int j=p[i].x;j>p[i].x-(p[i].x%K);j--) if(Y[j]<p[i].y) ans--; for(int j=p[i].y;j>p[i].y-(p[i].y%K);j--) if(X[j]<=p[i].x-(p[i].x%K)) ans--; X[p[i].y]=p[i].x,Y[p[i].x]=p[i].y; modify1D((p[i].x+K-1)/K,(p[i].y+K-1)/K,1); } printf("%lld ",ans); }