【BZOJ】【2253】【WC 2010 BeijingWC】纸箱堆叠

树套树



  Orz zyf

  我的树套树不知道为啥一直WA……只好copy了zyf的写法TAT

  这题还可以用CDQ分治来做……但是蒟蒻不会……

//y坐标的树状数组是按权值建的……所以需要离散化……

  1 /**************************************************************
  2     Problem: 2253
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:2808 ms
  7     Memory:76280 kb
  8 ****************************************************************/
  9
 10 //BZOJ 2253
 11 #include<cmath>
 12 #include<vector>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<cstdlib>
 16 #include<iostream>
 17 #include<algorithm>
 18 #define rep(i,n) for(int i=0;i<n;++i)
 19 #define F(i,j,n) for(int i=j;i<=n;++i)
 20 #define D(i,j,n) for(int i=j;i>=n;--i)
 21 #define pb push_back
 22 #define CC(a,b) memset(a,b,sizeof(a))
 23 using namespace std;
 24 int getint(){
 25     int v=0,sign=1; char ch=getchar();
 26     while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();}
 27     while(isdigit(ch))  {v=v*10+ch-‘0‘; ch=getchar();}
 28     return v*sign;
 29 }
 30 const int N=150010,M=3000000,INF=~0u>>2;
 31 typedef long long LL;
 32 const double eps=1e-8;
 33 /*******************template********************/
 34 int n,tot,l[M],r[M],s[M],rnd[M],v[M],f[N],mx[M];
 35 #define L l[x]
 36 #define R r[x]
 37 inline void Push_up(int x){ mx[x]=max(max(mx[L],mx[R]),s[x]); }
 38 inline void zig(int &x){int t=L; L=r[t]; r[t]=x; Push_up(x); Push_up(t); x=t;}
 39 inline void zag(int &x){int t=R; R=l[t]; l[t]=x; Push_up(x); Push_up(t); x=t;}
 40 void ins(int &x,int val,int num){
 41     if (!x){
 42         x=++tot; v[x]=val; s[x]=mx[x]=num; L=R=0; rnd[x]=rand(); return;
 43     }
 44     if(v[x]==val) s[x]=max(s[x],num);
 45     else if(val<v[x]){
 46         ins(L,val,num); if (rnd[L]<rnd[x]) zig(x);
 47     }else{
 48         ins(R,val,num); if (rnd[R]<rnd[x]) zag(x);
 49     }
 50     Push_up(x);
 51 }
 52 int rank(int x,int val){
 53     if (!x) return 0;
 54     if (v[x]==val) return max(mx[L],s[x]);
 55     else if (val<v[x]) return rank(L,val);
 56     else return max(max(s[x],mx[L]),rank(R,val));
 57 }
 58 #undef L
 59 #undef R
 60 /********************Treap**********************/
 61 int rt[N],_num,b[N],c[N],d[N];
 62 void update(int x,int val,int num){
 63     for(int i=x;i<=_num;i+=i&-i) ins(rt[i],val,num);
 64 }
 65 int query(int x,int val){
 66     int ans=0;
 67     for(int i=x;i;i-=i&-i) ans=max(ans,rank(rt[i],val));
 68     return ans;
 69 }
 70 /*******************Fenwick*********************/
 71 struct data{
 72     int x,y,z;
 73 }a[N];
 74 bool cmp(data a,data b){
 75     return a.x<b.x;
 76 }
 77 bool cmp2(int x,int y){return b[x]>b[y];}
 78 void init(){
 79     LL A=getint(),P=getint();
 80     n=getint();
 81     b[0]=1;
 82     F(i,1,n*3) b[i]=(LL)b[i-1]*A%P,c[i]=i;
 83     sort(c+1,c+3*n+1,cmp2);
 84     _num=0;
 85     F(i,1,3*n){
 86         if (i==1 || b[c[i]]!=b[c[i-1]]) _num++;
 87         d[c[i]]=_num;
 88     }
 89     F(i,1,n) a[i].x=d[3*i-2],a[i].y=d[3*i-1],a[i].z=d[3*i];
 90     F(i,1,n){
 91         if (a[i].y>a[i].x) swap(a[i].x,a[i].y);
 92         if (a[i].z>a[i].x) swap(a[i].x,a[i].z);
 93         if (a[i].z>a[i].y) swap(a[i].y,a[i].z);
 94     }
 95     sort(a+1,a+n+1,cmp);
 96 }
 97 int main(){
 98 #ifndef ONLINE_JUDGE
 99     freopen("input.txt","r",stdin);
100 //  freopen("output.txt","w",stdout);
101 #endif
102     init();
103     int ans=0;
104     for(int l=1,r=1;l<=n;r++,l=r){
105         while(a[r+1].x==a[l].x) r++;
106         F(i,l,r) f[i]=query(a[i].y-1,a[i].z-1)+1;
107         F(i,l,r) update(a[i].y,a[i].z,f[i]);
108     }
109     F(i,1,n) ans=max(f[i],ans);
110     printf("%d\n",ans);
111     return 0;
112 }
113 //y坐标的树状数组是按权值建的……所以需要离散化…… 

时间: 2024-10-16 14:15:16

【BZOJ】【2253】【WC 2010 BeijingWC】纸箱堆叠的相关文章

BZOJ2253: [2010 Beijing wc]纸箱堆叠

题解: 其实就是求三维偏序最长链.类似于三维逆序对,我们可以用树状数组套平衡树来实现. DP方程 :f[i]=max(f[j]+1) a[j]<a[i] 我们按一维排序,另一位建立树状数组,把第三维插入到每个树状数组的节点里. 除了权值之外每个节点还要保持一个mx,表示该子树内最大的f[i]. 这样就可以nlg^n了 UPD:试了下不带旋转的treap果然会被卡 orz 代码: 1 #include<cstdio> 2 3 #include<cstdlib> 4 5 #inc

【BZOJ2253】[2010 Beijing wc]纸箱堆叠 cdq分治

[BZOJ2253][2010 Beijing wc]纸箱堆叠 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个纸箱.在运输这些纸箱时,为了节约空间,必须将它们嵌套堆叠起来.一个纸箱可以嵌套

[bzoj 1911][Apio 2010]特别行动队(斜率优化DP)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1911 分析: 首先可以的到裸的方程f[i]=max{f[j]+a*(Si-Sj)^2+b*(Si-Sj)+c} 0<j<i 简化一下方程,我们知道对于一次项,最后结果肯定是b*Sn 所以可以写成f[i]=max{f[j]+a*(Si-Sj)^2+c} 0<j<i 我们不妨设0<x<y<i,且x比y优 即f[x]+a*(Si-Sx)^2+c>f[y]+a*

BZOJ2253 2010 Beijing wc 纸箱堆叠 CDQ分治

这题之前度娘上没有CDQ分治做法,gerwYY出来以后写了一个.不过要sort3遍,常数很大. gerw说可以类似划分树的思想优化复杂度,但是蒟蒻目前不会划分树(会了主席树就懒得去弄了). 嗯 将memset改成手动clear会快很多. 还有就是第一维相同的情况,划分为两个不存在第一维相同的两个区间即可. #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #inc

【BZOJ 1758】【WC 2010】重建计划 分数规划+点分治+单调队列

一开始看到$\frac{\sum_{}}{\sum_{}}$就想到了01分数规划但最终还是看了题解 二分完后的点分治,只需要维护一个由之前处理过的子树得出的$tb数组$,然后根据遍历每个当前的子树上的结点的深度来确定$tb数组$中的滑块. 因为分数规划要找的是$max$,BFS遍历当前结点的深度越来越大,这样滑块也是单调向右滑动,所以滑块里的最大值就应当用单调队列解决 #include<cstdio> #include<algorithm> #define read(x) x=ge

【待填坑】bzoj上WC的题解

之前在bzoj上做了几道WC的题目,现在整理一下 bzoj2115 去膜拜莫队的<高斯消元解xor方程组> bzoj2597 LCT维护MST bzoj1758 分数规划+树分治+单调队列 bzoj2595 斯坦纳树,一类用spfa转移的dp,具体可以膜拜<spfa算法的优化及应用>(我是不会插头的蒟蒻) bzoj2597 补集思想之后就变成了显然的平方流 bzoj3052 树上带修改莫队算法(如果一无所知的话,可以按2038 1086 3757 3052的顺序做) bzoj145

bzoj 1453: [Wc]Dface双面棋盘

1453: [Wc]Dface双面棋盘 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 617  Solved: 317[Submit][Status][Discuss] Description Input Output Sample Input Sample Output HINT 用线段树+数组模拟并查集,维护每一列的连通性,然后暴力合并就行了,常数巨大 #include<cstdio> #include<cstring> #inc

BZOJ 1975 SDOI 2010 魔法猪学院 A*求K短路

题目大意:给出一张无向图,给出一个数值m,求出从1到N的前k短路的长度和>=数值m. 思路:注意!不能使用priority_queue,否则你会死的很惨..为了解惑,我去找了当年SD省选的原题,分明空间是256M,为什么BZOJ和BASHUOJ上都是64M??卡pq有意思么??? 思路很简单,就是按顺序求出这张图的前k短路,然后当m减成负数的时候就返回. CODE: #include <queue> #include <cstdio> #include <cstring

BZOJ 2007 NOI 2010 海拔 平面图最小割-&gt;最短路SPFA+pq

题目大意:给出一个城市各个道路的双向流量,城市的左上角的高度是0,城市的右下角的高度是1,若人流升高海拔就会消耗体力,问最小需要消耗多少体力. 思路:这道题才是真正的让我见识到了algorithm中的heap的强大. 分析这道题可以发现,一定会有一条分界线,这个分界线左边高度都为0,右边高度都是1,然后找到这条分界点就可以了.明显的最小割.但是数据量巨大,直接跑最大流会T,又是平面图,建立对偶图然后跑最短路,SPFA+pq在BZOJ上可以很快,如果有的OJ卡STL的话可以考虑SPFA+Heap,