description
p 工廠是乙個生產紙箱的工廠。紙箱生產線在人工輸入三個引數 n p a , , 之後,即可自動化生產三邊邊長為
(a mod p,a^2 mod p,a^3 mod p)
(a^4 mod p,a^5 mod p,a^6 mod p)
…. (a^(3n-2) mod p,a^(3n-1) mod p,a^(3n) mod p)
的n個紙箱。在運輸這些紙箱時,為了節約空間,必須將它們巢狀堆疊起來。乙個紙箱可以巢狀堆疊進另乙個紙箱當且僅當它的最短邊、次短邊和最長邊長度分別嚴格小於另乙個紙箱的最短邊、次短邊和最長邊長度。這裡不考慮任何旋轉後在對角線方向的巢狀堆疊。你的任務是找出這n個紙箱中數量最多的乙個子集,使得它們兩兩之間都可巢狀堆疊起來。
input
輸入檔案的第一行三個整數,分別代表 a,p,n
output
輸出檔案僅包含乙個整數,代表數量最多的可巢狀堆疊起來的紙箱的個數
sample input
10 17 4
sample output
2solution
三維lis問題,cdq分治,按第一維x排序,由於此處是嚴格上公升,故在分治過程中mid值需要使得[l,,mid]的第一維嚴格小於[mid+1,r]的第一維,以dp[i]表示以第i個元素結尾的lis長度,則有dp[i]=max(dp[i],dp[j]+1),其中mid+1<=i<=r,l<=j<=mid,yj < yi,zj < zi,如果對[l,mid]和[mid+1,r]都按y為第一關鍵字,z為第二關鍵字公升序排,每次計算dp[i]之前將所有滿足yj < yi的j都以zj為下標,dp[j]為鍵值插入到樹狀陣列中,那麼問題轉化為求樹狀陣列中下標小於zi的最大值,最後的答案為max(dp[i])
code
#include
#include
#include
#include
using namespace std;
#define maxn 111111
int a,p,n,t[maxn],tot;
struct node
}p[maxn];
int cmpx(node a,node b)
void update(int
x,int v)
}int query(int
x)
return ans;
}void clear(int
x)
}}bit;
void cdq(int l,int r)
if(tr
<=r&&p[tr-1].x!=p[tr].x)
tl--,tr++;
}if(mid==-1)return ;
cdq(l,mid);
sort(p+l,p+mid+1,cmpy);
sort(p+mid+1,p+r+1,cmpy);
for(int i=mid+1,j=l;i<=r;i++)
for(int i=l;i<=mid;i++)bit.clear(p[i].z);
sort(p+mid+1,p+r+1,cmpx);
cdq(mid+1,r);
}int main()
sort(p+1,p+n+1,cmpx);
sort(t+1,t+tot+1);
for(int i=1;i<=n;i++)
p[i].z=lower_bound(t+1,t+tot+1,p[i].z)-t;
cdq(1,n);
int ans=1;
for(int i=1;i<=n;i++)ans=max(ans,p[i].ans);
printf("%d\n",ans);
return
0;}
bzoj2253 紙箱堆疊
題目鏈結 求三元組的嚴格上公升子串行 先考慮暴力 dp 一下 for int i 1 i n i for int j 1 j i j if x i x j y i y j z i z j f i max f i f j 1 考慮用 cdq 分治優化這個 dp 大體思路是,先按照第一維排序,保證第一維...
BZOJ2253 紙箱堆疊 CDQ分治
time limit 30 sec memory limit 256 mb submit status discuss p 工廠是乙個生產紙箱的工廠。紙箱生產線在人工輸入三個引數 n p a 之後即可自動化生產三邊邊長為 a mod p,a 2 mod p,a 3 mod p a 4 mod p,a...
2253 Frogger 解題報告
accecpttime 2008 12 30 11 11 23 language c memory 572k time 16ms errors 2wa algorithm dijkstra最短路徑 include include include include include using names...