标签:线段树
题意: 东海岸有x个城市,西海岸有y个。x与y 之间有很多高速公路。问k条路有多少个交叉点。
我就是求的逆序对,把east当作 pos 按照从大到小排序。然后插入。接下来的就跟求逆序对的一样了。
线段树或者数状数组都能过。
注意最后要用long long。
(午夜一发,写完吃个面包睡觉。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<bitset> #include<vector> #include<cmath> #define INF 0x7fffffff #define eps 1e-8 #define LL long long #define PI 3.141592654 #define CLR(a,b) memset(a,b,sizeof(a)) #define FOR(i,a,b) for(int i=a;i<b;i++) #define FOR_(i,a,b) for(int i=a;i>=b;i--) #define sf scanf #define pf printf #define all(v) (v).begin(),(v).end() #define acfun std::ios::sync_with_stdio(false) #define SIZE (1000 +2) #define MOD 1000000007 using namespace std; int a[SIZE*4]; int up; void update(int l,int r,int o) { if(l==r) a[o]++; else { int m=(l+r)>>1; if(up<=m)update(l,m,o*2); else update(m+1,r,o*2+1); a[o]=a[o*2]+a[o*2+1]; } } int ql,qr; int query(int l,int r,int o) { if(l>=ql&&r<=qr)return a[o]; int m=(l+r)>>1; int ans=0; if(ql<=m)ans+=query(l,m,o*2); if(qr>m)ans+=query(m+1,r,o*2+1); return ans; } struct node { int e,w; bool friend operator <(node a,node b) { if(a.e==b.e) return a.w>b.w; return a.e>b.e; } }way[SIZE*SIZE]; int main() { int t; int east,west,n; sf("%d",&t); FOR(tt,1,t+1) { sf("%d%d%d",&east,&west,&n); FOR(i,0,n) sf("%d%d",&way[i].e,&way[i].w); sort(way,way+n); CLR(a,0); LL ans=0; FOR(i,0,n) { up=way[i].w; update(1,west,1); ql=1,qr=way[i].w-1; if(ql<=qr) ans+=query(1,west,1); } pf("Test case %d: %lld\n",tt,ans); } }
标签:线段树
原文地址:http://blog.csdn.net/dongshimou/article/details/43862461