#includeusing namespace std;
typedef long long ll;
const int n=5e5+9;
int a[n],temp[n],n;
ll ans=0;
void merge_sort(int l,int r)
while(p<=mid)temp[x++]=a[p++];
for(int i=l;i<=r;i++)a[i]=temp[i];
}int main()a[n];
int b[m],rk[n],v[n];
int n,k;
bool cmp1(t t1,t t2)
for(int i=l;i>n>>k;
for(int i=1;i<=n;++i)cin>>a[i].x>>a[i].y>>a[i].z;
sort(a+1,a+n+1,cmp1);
int nn=0,c=0;
for(int i=1;i<=n;i++)
cdq(1,nn);
for(int i=1;i<=nn;i++)v[a[i].ans+a[i].cnt-1]+=a[i].cnt;
for(int i=0;ipoints and rectangles(這裡不用注意下一題的排序,因為它的時間,第一維就是遞增的)
題意:
輸入q(1e5),接下來q行;
每行輸入 1,x,y 表示在平面上加乙個點
或 2,x1,y1,x2,y2 表示在平面上加乙個矩形
問對於每乙個操作後,有多少個對點和矩形(點在矩形內)
題解:
經典偏序問題,按時間,橫座標,縱座標形成三維偏序。
分兩種情況:
1、矩形對答案的貢獻,設矩形為(t,x1,y1,x2,y2),即算在小於t時間的sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1],
2、點對答案的貢獻,設點為(x,y)與上面符號相反的求就好了。
#includeusing namespace std;
typedef long long ll;
const int n=1e6+9;
int q,na,x[n],y[n],nx,ny;
struct ta[n];
ll ans[n];
int f[n];
void add(int x,int y)
if(a[i].id==1)ans[a[i].t]+=query(a[i].y)*a[i].z;
}for(int i=l;i=mid+1;i--)
if(a[i].id==0)ans[a[i].t]+=query(n-2)-query(a[i].y-1);
}for(int i=mid;i>p;i--)if(a[i].id==1)add(a[i].y,-a[i].z);
}int main(),x[++nx]=x1,y[++ny]=y1;
if(opt==2);
a[++na]=(t);
a[++na]=(t);
a[++na]=(t);}}
sort(x+1,x+nx+1),sort(y+1,y+ny+1);
nx=unique(x+1,x+nx+1)-x-1,ny=unique(y+1,y+ny+1)-y-1;
for(int i=1;i<=na;i++)a[i].x=getidx(a[i].x),a[i].y=getidy(a[i].y);
cdq(1,na);
for(int i=1;i<=q;i++)ans[i]+=ans[i-1],printf("%lld\n",ans[i]);
return 0;
}
twinkle(排序一定要注意 插入優先於查詢,我因為這個調了乙個半小時)
題意:
輸入n(5e4),q(5e4),c(1e9);分別表示n顆星星,q個詢問,星星最大亮度為c(c+1變0)
接下來n行輸入x,y,s(s<=c),表示x,y處有一顆亮度為s的星星。
接下來輸入q行;
每行輸入t(t<=c),x1,y1,x2,y2;問過了t時間該矩形內星星的亮度和為多少。
題解:
由於s+t<=2*c,所以最多減一次c就可,先把矩形內星星亮度取和,加上t的貢獻,最後減去多少個超過c的貢獻。
現在要求該矩形內星星個數和星星亮度大於c-t的個數。
於是就變成了乙個求(橫座標,縱座標,星星亮度)的三維偏序問題;(注意星星盡量放前面)
#includeusing namespace std;
typedef long long ll;
const int n=1e6+9;
int n,q,c,na,nx;
int f[n],x[n],tim[n];
void add(int x,int y)
if(a[i].id)gs[a[i].id]+=js*a[i].z,ans[a[i].id]+=he*a[i].z,les[a[i].id]+=query(a[i].s)*a[i].z;
}for(int i=l;i>n>>q>>c;
for(int i=1,xx,y,s;i<=n;i++)cin>>xx>>y>>s,a[++na]=(t),x[++nx]=s;
for(int i=1,t,x1,y1,x2,y2;i<=q;i++);
a[++na]=(t);
a[++na]=(t);
a[++na]=(t);
x[++nx]=c-t;
}sort(x+1,x+nx+1);nx=unique(x+1,x+nx+1)-x-1;
for(int i=1;i<=na;i++)a[i].s=getidx(a[i].s);
sort(a+1,a+na+1,cmp1);
cdq(1,na);
for(int i=1;i<=q;i++)cout<四維偏序問題:
四維偏序裸題思路,cdq套cdq即a通過flag標記,在cdq2的時候,b已經是有序的了,所以只用再c歸併,d樹狀陣列求和。
#include #include #include #include using namespace std;
typedef long long ll;
const int n=5e4+5;
inline int read()
while(c>='0'&&c<='9')
return x*f;
}int n;
struct operationa[n],t1[n],t2[n];
int c[n];
inline int lowbit(int x)
inline void add(int p,int v)
inline int sum(int p)
int ans;
void cdq2(int l,int r)
for(int i=l;i<=r;i++) a[i]=t[i];
cdq2(l,r);
}int main()
歸併排序(分治)
把乙個陣列 a 分成兩個部分 s,m m 1,e 假設兩部分分別有序,把這兩部分合併到另一陣列中 tmp 保證該陣列有序,然後再把資料 e s 1拷貝回陣列a 分治的原理。把資料無限二分,最後比較兩個數即可。遞迴實現。includeusing namespace std int a 10 int b...
歸併排序 分治
歸併 將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有 序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。歸併的本質 空間換時間,通過申請乙個額外陣列儲存中間變化,從而實現排序 歸併排序核心步驟 歸併排序的特性總結 歸併的缺點在於需要o n 的空間複雜度,歸併排序的思...
分治 歸併排序
將兩個排序好的陣列歸併過程如下 紅色的 1 是左邊起始位置 綠色的 2 是右邊起始位置 灰色的 最右邊 是右邊終點位置 include using namespace std typedef int elementtype l 左邊起始位置,r 右邊起始位置,rightend 右邊終點位置 void...