NOIP 模擬 6 辣雞
阿新 • • 發佈:2021-06-11
題解
難得啊,本來能 \(AC\) 的一道題,註釋沒刪,掛了五分,難受
此題暴力很好想,就是直接 \(n^2\) 列舉不同的矩陣組合,記錄塊內答案和跨塊的答案
出題人不會告訴你,這題只要輸出塊內答案就可以拿到 \(65pts\) 。
一個很簡單的優化就是按 \(x_1\) 的值先排個序,然後判斷
if (mat[j].x1-mat[i].x2>1) break;
但是這種玄學優化仍可以被上下一條鏈似的塊卡掉,但良心出題人竟然沒卡。
正解應該是按兩維的座標均排個序,然後二分查詢,求出符合要求的塊,複雜度 \(\mathcal O(nlogn)\)
我不會告訴你其實常數小的暴力其實比正解還快了一倍
Code
\(AC\kern 0.4em CODE:\)
#include<bits/stdc++.h> #define ri register int #define p(i) ++i using namespace std; namespace IO{ char buf[1<<21],*p1=buf,*p2=buf; #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++ inline int read() { ri x=0,f=1;char ch=gc(); while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();} while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();} return x*f; } } using IO::read; namespace nanfeng{ #define int long long #define cmax(x,y) ((x)>(y)?(x):(y)) #define cmin(x,y) ((x)>(y)?(y):(x)) #define FI FILE *IN #define FO FILE *OUT #undef bool static const int N=1e5+7; struct Matrix{ int x1,y1,x2,y2; friend inline bool operator<(Matrix m1,Matrix m2) {return m1.x1<m2.x1;} Matrix(){} Matrix(int x1,int y1,int x2,int y2):x1(x1),y1(y1),x2(x2),y2(y2){} }mat[N]; int n,ans; inline int calc(Matrix m) { int res=0; int x=m.x2-m.x1,y=m.y2-m.y1; if (x>y) swap(x,y); res+=(x*x<<1); res+=(y-x)*(x<<1); return res; } inline int main() { // FI=freopen("nanfeng.in","r",stdin); // FO=freopen("nanfeng.out","w",stdout); n=read(); for (ri i(1);i<=n;p(i)) { int x1=read(),y1=read(),x2=read(),y2=read(); mat[i]=Matrix(x1,y1,x2,y2); } if (n==1) {printf("%lld\n",calc(mat[1]));return 0;} sort(mat+1,mat+n+1); // for (ri i(1);i<=n;p(i)) for (ri i(1);i<n;p(i)) { ans+=calc(mat[i]); // printf("%lld %lld %lld %lld\n",mat[i].x1,mat[i].y1,mat[i].x2,mat[i].y2); for (ri j(i+1);j<=n;p(j)) { if (mat[j].x1-mat[i].x2>1) break; if (mat[j].x1-mat[i].x2==1) { if (mat[j].y1-mat[i].y2>1||mat[i].y1-mat[j].y2>1) continue; if (mat[j].y1-mat[i].y2==1||mat[i].y1-mat[j].y2==1) {ans+=1;continue;} ans+=(cmin(mat[i].y2,mat[j].y2)-cmax(mat[i].y1,mat[j].y1))<<1; if (cmax(mat[i].y2,mat[j].y2)>cmin(mat[i].y2,mat[j].y2)) ans+=1; if (cmax(mat[i].y1,mat[j].y1)>cmin(mat[i].y1,mat[j].y1)) ans+=1; } else if (mat[j].y1>mat[i].y2) { if (mat[j].y1-mat[i].y2>1) continue; ans+=(cmin(mat[i].x2,mat[j].x2)-mat[j].x1)<<1; if (mat[i].x1<mat[j].x1) ans+=1; if (cmax(mat[i].x2,mat[j].x2)>cmin(mat[i].x2,mat[j].x2)) ans+=1; } else { if (mat[i].y1-mat[j].y2>1) continue; ans+=(cmin(mat[i].x2,mat[j].x2)-mat[j].x1)<<1; if (mat[i].x1<mat[j].x1) ans+=1; if (cmax(mat[i].x2,mat[j].x2)>cmin(mat[i].x2,mat[j].x2)) ans+=1; } // if (i==2) printf("%lld %lld %lld %lld ans=%lld\n",mat[j].x1,mat[j].y1,mat[j].x2,mat[j].y2,ans); } // printf("ans=%lld\n",ans); } // printf("%lld %lld %lld %lld\n",mat[n].x1,mat[n].y1,mat[n].x2,mat[n].y2); printf("%lld\n",ans+calc(mat[n])); return 0; } #undef int } int main() {return nanfeng::main();}