Advertisement
najim

1432 - Overlapping Sticks_WA_nofraction

Nov 21st, 2013
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.38 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define fst first
  4. #define snd second
  5. typedef long long DT;
  6. #define MP make_pair
  7. typedef long long LLI;
  8. #define REP(i,n) for(int i=0;i<n;i++)
  9. #define PB push_back
  10. #define SORT(x) sort(x.begin(),x.end())
  11. template<class T> inline T gcd(T a, T b)
  12. {
  13.     if (a < 0)return gcd(-a, b);
  14.     if (b < 0)return gcd(a, -b);
  15.     return (b == 0) ? a : gcd(b, a % b);
  16. }
  17.  
  18. struct Point
  19. {
  20.     DT x,y;
  21.     Point() {}
  22.     Point(DT _x,DT _y)
  23.     {
  24.         x=_x;
  25.         y=_y;
  26.     }
  27. };
  28.  
  29. struct Line
  30. {
  31.     Point st,ed;
  32.     Line() {}
  33.     Line(Point _x,Point _y)
  34.     {
  35.         st=_x;
  36.         ed=_y;
  37.     }
  38.     void show()
  39.     {
  40.         cout << st.x << " " << st.y << endl;
  41.         cout << ed.x << " " << ed.y << endl;
  42.     }
  43. };
  44.  
  45. long long inf = 100000000LL;
  46. long long INF = 100000000LL;
  47. Line xaxis=Line(Point(-INF,0),Point(INF,0));
  48.  
  49. pair<DT,DT> LineLineIntersection(Line A,Line B)
  50. {
  51.     DT A1 = A.ed.y-A.st.y;
  52.     DT B1 = A.st.x-A.ed.x;
  53.     DT C1 = A1*A.st.x+B1*A.st.y;
  54.  
  55.     DT A2 = B.ed.y-B.st.y;
  56.     DT B2 = B.st.x-B.ed.x;
  57.     DT C2 = A2*B.st.x+B2*B.st.y;
  58.  
  59.     DT det=A1*B2 - A2*B1;
  60.  
  61.     if(det == 0)
  62.     {
  63.         return MP(INF,INF);
  64.         //Lines are parallel
  65.     }
  66.     else
  67.     {
  68.         double x,y;
  69.         DT ra=0,rb=0;
  70.         if((B2*C1 - B1*C2)==0)
  71.         {
  72.             x=0;
  73.             ra=0,rb=1;
  74.         }
  75.         else
  76.         {
  77.             x = ((B2*C1 - B1*C2)*(1.0))/det;
  78.             ra=(B2*C1 - B1*C2);
  79.             rb=det;
  80.         }
  81.  
  82.         if((A1*C2 - A2*C1)==0)y=0;
  83.         else y = ((A1*C2 - A2*C1)*(1.0))/det;
  84.  
  85.         if(ra && rb)
  86.         {
  87.             DT g=gcd(ra,rb);
  88.             ra/=g;
  89.             rb/=g;
  90.         }
  91.         return MP(ra,rb);
  92.     }
  93. }
  94.  
  95. struct Z
  96. {
  97.     Line a;
  98.     DT dx,dy;
  99.     pair<DT,DT> x;// where line obect intersect X axis
  100.     Z() {}
  101.     Z(Line _l)
  102.     {
  103.         a=_l;
  104.         dy=a.ed.y-a.st.y;
  105.         dx=a.ed.x-a.st.x;
  106.         if(dy && dx)
  107.         {
  108.             DT g=__gcd(abs(dx),abs(dy));
  109.             dx/=g;
  110.             dy/=g;
  111.         }
  112.         x=LineLineIntersection(xaxis,a);
  113.     }
  114.     bool friend operator < (Z A, Z B)
  115.     {
  116. //        if(A.dy*B.dx==A.dx*B.dy)
  117. //        {
  118. //            return (A.x.first*B.x.second<A.x.second*B.x.first);
  119. //        }
  120. //        return A.dy*B.dx<A.dx*B.dy;// lines are not paralel
  121.  
  122.         if((A.x.first*B.x.second==A.x.second*B.x.first))
  123.         {
  124.             return A.dy*B.dx<A.dx*B.dy;
  125.         }
  126.         return A.x.first*B.x.second<A.x.second*B.x.first;
  127.     }
  128. };
  129.  
  130. vector<Z>V;
  131.  
  132. bool same(Z A, Z B)
  133. {
  134.     return (A.dy*B.dx==B.dy*A.dx);
  135. }
  136.  
  137. bool CoLine(Z A ,Z B)
  138. {
  139.     return (A.x.first*B.x.second==A.x.second*B.x.first);
  140. }
  141.  
  142. struct P
  143. {
  144.     Point cp;
  145.     int type;
  146.     P() {}
  147.     P(Point _cp,int _t)
  148.     {
  149.         cp=_cp;
  150.         type=_t;
  151.     }
  152.     bool friend operator < (P A, P B)
  153.     {
  154.         if(A.cp.x==B.cp.x && A.cp.y==B.cp.y)
  155.         {
  156.             return A.type<B.type;
  157.         }
  158.         if(A.cp.x==B.cp.x)return  A.cp.y<B.cp.y;
  159.         return A.cp.x<B.cp.x;
  160.     }
  161. };
  162.  
  163. Z Arg[100009];
  164. int sza;
  165. LLI solve()
  166. {
  167.     if(sza<=1)return 0;
  168.     vector<P>tmp;
  169.     REP(i,sza)
  170.     {
  171.         tmp.PB(P(Arg[i].a.st,1));
  172.         tmp.PB(P(Arg[i].a.ed,-1));
  173.     }
  174.     SORT(tmp);
  175.  
  176.     int lim=2*sza;
  177.     int act=0;
  178.     long long ret=0;
  179.     for(int i=0; i<lim; i++)
  180.     {
  181.         if(tmp[i].type==1)
  182.         {
  183.             if(act>=0)ret+=act;
  184.             act++;
  185.         }
  186.         else act--;
  187.     }
  188.     //cout << ret << endl;
  189.     return ret;
  190. }
  191. vector<Z>X,Y;
  192.  
  193. bool compx(Z A,Z B)
  194. {
  195.     if(A.a.st.y==B.a.st.y)return A.a.st.x<B.a.st.x;
  196.     return A.a.st.y<B.a.st.y;
  197. }
  198.  
  199. bool compy(Z A,Z B)
  200. {
  201.     if(A.a.st.x==B.a.st.x)return A.a.st.y<B.a.st.y;
  202.     return A.a.st.x<B.a.st.x;
  203. }
  204.  
  205. LLI solveX()
  206. {
  207.     if(X.size()==0)return 0;
  208.     sort(X.begin(),X.end(),compx);
  209.     LLI ret=0;
  210.     sza=0;
  211.     Arg[sza++]=X[0];
  212.     for(int i=1; i<X.size(); i++)
  213.     {
  214.         if(X[i].a.st.y==X[i-1].a.st.y)
  215.         {
  216.             Arg[sza++]=X[i];
  217.         }
  218.         else
  219.         {
  220.             ret+=solve();
  221.             sza=0;
  222.             Arg[sza++]=X[i];
  223.         }
  224.     }
  225.     if(sza>1)ret+=solve();
  226.     return ret;
  227. }
  228. LLI solveY()
  229. {
  230.     if(Y.size()==0)return 0;
  231.     sort(Y.begin(),Y.end(),compy);
  232.     LLI ret=0;
  233.     sza=0;
  234.     Arg[sza++]=Y[0];
  235.     for(int i=1; i<Y.size(); i++)
  236.     {
  237.         if(Y[i].a.st.x==Y[i-1].a.st.x)
  238.         {
  239.             Arg[sza++]=Y[i];
  240.         }
  241.         else
  242.         {
  243.             ret+=solve();
  244.             sza=0;
  245.             Arg[sza++]=Y[i];
  246.         }
  247.     }
  248.     if(sza>1)ret+=solve();
  249.     return ret;
  250. }
  251.  
  252.  
  253. int main()
  254. {
  255.     int kase,ks=0;
  256.     scanf("%d",&kase);
  257.     while(kase--)
  258.     {
  259.         V.clear();
  260.         X.clear();
  261.         Y.clear();
  262.         int N;
  263.         scanf("%d",&N);
  264.         LLI x1,y1,x2,y2;
  265.         REP(i,N)
  266.         {
  267.             scanf("%lld %lld %lld %lld",&x1,&y1,&x2,&y2);
  268.             if(x1>x2 || (x1==x2 && y1>y2))
  269.             {
  270.                 swap(x1,x2);
  271.                 swap(y1,y2);
  272.             }
  273.             if(x2-x1==0)Y.PB(Line(Point(x1,y1),Point(x2,y2)));
  274.             else if(y2-y1==0)X.PB(Line(Point(x1,y1),Point(x2,y2)));
  275.             else V.PB(Line(Point(x1,y1),Point(x2,y2)));
  276.         }
  277.         long long res=0;
  278.         long long ct=1;
  279.         if(!V.empty())
  280.         {
  281.             SORT(V);
  282.             sza=0;
  283.             Arg[sza++]=V[0];
  284.  
  285.             for(int i=1; i<V.size(); i++)
  286.             {
  287.                 if(same(V[i],V[i-1]))//slope
  288.                 {
  289.                     if(CoLine(V[i],V[i-1]))
  290.                     {
  291.                         Arg[sza++]=V[i];
  292.                     }
  293.                     else
  294.                     {
  295.                         res+=(solve());
  296.                         sza=0;
  297.                         Arg[sza++]=V[i];
  298.                     }
  299.                 }
  300.                 else
  301.                 {
  302.                     res+=(solve());
  303.                     sza=0;
  304.                     Arg[sza++]=V[i];
  305.                 }
  306.             }
  307.             if(sza>1)res+=solve();
  308.         }
  309.         //cout << "......." << res << endl;
  310.         res+=solveX();
  311.         res+=solveY();
  312.         printf("Case %d: %lld\n",++ks,res);
  313.     }
  314.     return 0;
  315. }
  316. /*
  317. 2
  318. 13
  319. 1 0 5 0
  320. 5 0 8 0
  321. 4 0 6 0
  322. 0 0 10 0
  323.  
  324. 2 0 6 4
  325. 3 1 6 4
  326. 4 2 7 5
  327.  
  328. -6 0 0 -6
  329. -5 -1 -7 1
  330. -1 -5 1 -7
  331.  
  332. 2 1 2 3
  333. 2 2 2 -4
  334. 2 -1 2 10
  335. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement