链接:http://cogs.pro:8080/cogs/problem/problem.php?pid=2262
题意:求出三维偏序中顺序对的数量。
虽说打过$CDQ$……但是三个月了又跟没打过有什么区别……不说了……
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn=200005; 7 struct node 8 { 9 int from,to,dis,next; 10 }edge[maxn<<1]; 11 int head[maxn],tot; 12 void addedge(int u,int v,int w) 13 { 14 edge[++tot]=(node){u,v,w,head[u]};head[u]=tot; 15 } 16 struct ques 17 { 18 int id,d,val; 19 inline bool operator <(const ques &b)const 20 { 21 if(d!=b.d)return d<b.d; 22 return id<b.id; 23 } 24 }A[maxn],B[maxn]; 25 void dfs(int root,int pa) 26 { 27 for(int i=head[root];i;i=edge[i].next) 28 { 29 int v=edge[i].to; 30 if(v!=pa)A[v].d=A[root].d+edge[i].dis,dfs(v,root); 31 } 32 } 33 int n; 34 int C[maxn]; 35 int lowbit(int x) 36 { 37 return x&(-x); 38 } 39 void Modify(int pos,int val) 40 { 41 for(;pos<=n;pos+=lowbit(pos))C[pos]+=val; 42 } 43 int Query(int pos) 44 { 45 int res=0; 46 for(;pos;pos-=lowbit(pos))res+=C[pos]; 47 return res; 48 } 49 long long ans; 50 void CDQ(int l,int r) 51 { 52 if(l>=r)return; 53 int mid=(l+r)>>1;CDQ(l,mid);CDQ(mid+1,r); 54 int l1=l,l2=mid+1,now=l; 55 while(l1<=mid&&l2<=r) 56 if(A[l1]<A[l2])B[now++]=A[l1++]; 57 else B[now++]=A[l2++]; 58 while(l1<=mid)B[now++]=A[l1++]; 59 while(l2<=r)B[now++]=A[l2++]; 60 for(int i=l;i<=r;i++)A[i]=B[i]; 61 for(int i=l;i<=r;i++) 62 if(A[i].id<=mid)Modify(A[i].val,1); 63 else ans+=Query(A[i].val); 64 for(int i=l;i<=r;i++) 65 if(A[i].id<=mid)Modify(A[i].val,-1); 66 } 67 int haha() 68 { 69 freopen("ZZ.in","r",stdin); 70 freopen("ZZ.out","w",stdout); 71 scanf("%d",&n); 72 for(int i=1;i<=n;i++)scanf("%d",&A[i].val),A[i].id=i; 73 for(int i=1;i<n;i++) 74 { 75 int x,y,z;scanf("%d%d%d",&x,&y,&z); 76 addedge(x,y,z);addedge(y,x,z); 77 } 78 dfs(1,0);CDQ(1,n);printf("%lld ",ans); 79 } 80 int sb=haha(); 81 int main(){;}