JZOJ 4018 Magic
Description
圆上有 2 ∗ n 个点和连接这些点的 n 条弦,这些弦不会在圆上相交。这2 ∗ n 个点按照在圆上的位置顺序依次标号为 1,2,...,2 ∗ n。
请求出有多少个无序的三元组,使得对应的三条弦可以通过距离的缩放中心对称。
请求出有多少个无序的三元组,使得对应的三条弦可以通过距离的缩放中心对称。
Input
第一行一个数 n (n ≤ 100000)。
接下来 n 行,每行两个数,表示该弦的端点。保证一个数不会出现两次。
接下来 n 行,每行两个数,表示该弦的端点。保证一个数不会出现两次。
Output
输出一个数,表示方案数。
Sol
读不懂题系列,(⊙o⊙)…
原题cf 297E。
题目让我们找三条线段让两两端点距离相等。
不知道为什么,我写了个莫队。
#pragma GCC optimize("-Ofast") #include<bits/stdc++.h> #define pii pair<int,int> #define x first #define N 2000007 #define y second using namespace std; #define sight(x) ('0'<=x&&x<='9') inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } int n,l,r,B; inline bool cmp(pii X,pii Y) { return (X.x/B==Y.x/B)?(X.y<Y.y):(X.x<Y.x); } int li,ri,zi,now[N],id[N],s,R[N],s2[N];pii p[N]; inline void add(int x){ zi+=now[id[x]]?-1:1; now[id[x]]^=1; } signed main () { freopen("magic6.in","r",stdin); scanf("%d",&n); B=sqrt(7*n); for (int i=1;i<=n;i++) { read(p[i].x); read(p[i].y); if (p[i].x>p[i].y) swap(p[i].x,p[i].y); id[p[i].x]=i; id[p[i].y]=i; } sort(p+1,p+n+1,cmp); long long ans=1ll*n*(n-1)/2*(n-2)/3; l=1; for (int i=1;i<=n;i++) { while (r<p[i].y) add(++r); while (l>p[i].x) add(--l); while (r>p[i].y) add(r--); while (l<p[i].x) add(l++); li=p[i].y-1-p[i].x-zi>>1; ri=n-1-zi-li; ans-=1ll*li*ri; ans-=1ll*(n-1-zi)*zi/2; } printf("%lld\n",ans); return 0; // for (int i=1;i<=2*n;i++) { // // } return 0; }