B组题都能考爆炸我是完了……
考试过程:
死刚一道题这种事情又不是第一次干怎么还敢这么搞啊??
T1一看dp嘛,和‘扫雷游戏’有点像(我是dp学傻了),打了个$n^2$的线性dp(考完之后才发现这部就是卡特兰数吗??),然后就想dp怎么优化,想了好久没有思路。去看T2,好像不可做,线段树?应该吧……T3,woc?Alpaca L. Sotomon是个什么玩意……看了看题,有向图,tarjan?拓扑?好像可以,复杂度都是$On$,只有建边是$n^2$的,什么鬼玩意,图论复杂度死于建边??想了想塞vector吧,然而有一种情况不会处理只会暴扫(怎么就没想起map呢??)手模几组样例发现没问题就过了。又看了看T1,觉得这个dp没前途好像没办法优化,换个状态定义?好像并不行……写T2吧,话说这数据范围给的是个啥,好像$mn$一分都没有,我打了一个$mn^2$的大暴力,估计得不了分,m次是一次一次模拟的,是不是有没有必要的计算呢?好像开始都是可以够到的,所以可以记录一下每个井能够下降的次数用线段树维护最大最小值,每次查询剩下大于n的个数,如果等于n直接跳过这一轮就做到了对无用枚举的加速,本来以为可以多拿点分结果数据好像很强???全部挂掉……之所以后来没有去想T1是因为觉得可能是个神仙dp毕竟我连状态定义都没想出来但相比之下T2至少有了方向所以改T2在当时来说可能是个更优的选则,然而我为什么一直以为T1是dp啊……
考试总结:
1.死刚一道题这种事还是尽量不要干的好,虽然这次是分析了一下认为应该刚T2,但是是由于难度判断出错。
2.d什么p,方案数除了dp还有组合数卡特兰数啊。遇到一个题一眼看上去是dp但是它不一定就是啊,要从各个方面想想,回顾一下学过的知识。
A. 字符串
就是裸的卡特兰数我居然没有看出来……

1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #define mod 20100403
5 #define MAXN 1000010
6 #define LL long long
7 using namespace std;
8 int n,m;
9 LL f[2][MAXN];
10 inline int read();
11 signed main()//取模!!!!!!!!!!!!
12 {
13 n=read(),m=read();
14 // if(n+m<=5000)
15 {
16 int maxx=m+n;f[1][1]=1;
17 for(int i=2;i<=maxx;i++)
18 {
19 int now=i%2,pre=(i-1)%2;
20 for(int j=0;j<=min(i,n);j++)//1的个数
21 if(j>=(i-j))
22 {
23 if(j-1>=i-j)f[now][j]=(f[now][j]+f[pre][j-1])%mod;
24 if(i-j-1>=0)f[now][j]=(f[now][j]+f[pre][j])%mod;
25 // cout<<i<<" "<<j<<" "<<i-j<<" "<<f[now][j]<<endl;
26 }
27 for(int j=0;j<=min(i,n);j++)//1的个数
28 f[pre][j]=0;
29 }
30 LL ans=0;ans=f[maxx%2][n];
31 printf("%lld\n",ans%mod);
32 return 0;
33 }
34 }
35 inline int read()
36 {
37 int s=0,f=1;char a=getchar();
38 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
39 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
40 return s*f;
41 }

1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #define mod 20100403
5 #define MAXN 1000010
6 #define LL long long
7 using namespace std;
8 int n,m;
9 LL jc[2000010];
10 LL poww(LL a,int b)
11 {
12 LL ans=1;
13 while(b)
14 {
15 if(b&1)ans=ans*a%mod;
16 a=a*a%mod;
17 b=b>>1;
18 }
19 return ans;
20 }
21 LL C(int n,int m){return jc[n]*poww(jc[m],mod-2)%mod*poww(jc[n-m],mod-2)%mod;}
22 inline int read();
23 signed main()//取模!!!!!!!!!!!!
24 {
25 n=read(),m=read();
26 jc[0]=1;
27 for(int i=1;i<=m+n;i++)jc[i]=(jc[i-1]*i)%mod;
28 LL ans=((C(m+n,m)-C(m+n,m-1))%mod+mod)%mod;
29 printf("%lld\n",ans);
30 }
31 inline int read()
32 {
33 int s=0,f=1;char a=getchar();
34 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
35 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
36 return s*f;
37 }
B. 乌鸦喝水
这是一个比较神仙的贪心。
对于每口井每次下降的高度不一样就很烦,有没有一样的呢?一共可以下降的次数,这个没次只改变1,设为b。
水缸次数少的一定会在次数多的前面喝完,抓住这个性质,我们把水缸次数排个序,然后一个一个处理过去即可。
那么我们可以省掉m的循环枚举,直接扫每一口井。
假设前面一共喝了tu轮。
对于第i口井,可以知道还剩s口井,二分出一个答案cnt,表示第i口井除了前面喝的还可以被喝的次数。使cnt满足s*cnt<b(i)-last,cnt的最大值。
last表示之前的每一口井喝的总次数。水位是一起下降的。
第i口井还可以喝cnt轮,那么后面的井也一定还可以喝cnt轮。
num[i]表示井i可以喝的次数。那么num[i]=tu+cnt(之前喝了几轮+这次可以喝几轮)。
这样就只是算了整数圈,最后还会再剩下一圈零的,就要单独考虑能喝到哪里,判断序号小于id[i]且仍存在的井的个数(用树状数组),是否可以让第i口井再喝一次(也就是剩余的次数是否大于 在该井之前包括该井的井数,能则last++,num[i]++)。

1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #define MAXN 100010
6 #define int LL
7 #define LL long long
8 using namespace std;
9 struct tree
10 {
11 int l,r,mi,la,ma;
12 #define l(x) tr[x].l
13 #define r(x) tr[x].r
14 #define mi(x) tr[x].mi
15 #define ma(x) tr[x].ma
16 #define la(x) tr[x].la
17 #define ls(x) ((x)<<1)
18 #define rs(x) (ls(x)+1)
19 }tr[MAXN*4];
20 int n,m,x;
21 int w[MAXN],a[MAXN],b[MAXN],pos[MAXN];
22 void down(int x)
23 {
24 if(l(x)==r(x)||la(x)==0)return;
25 la(ls(x))=la(rs(x))=la(x);
26 mi(ls(x))+=la(x);mi(rs(x))+=la(x);
27 ma(ls(x))+=la(x);ma(rs(x))+=la(x);
28 la(x)=0;
29 }
30 void build(int x,int l,int r)
31 {
32 l(x)=l,r(x)=r;
33 if(l==r){mi(x)=ma(x)=b[l];pos[l]=x;return;}
34 int mid=(l+r)>>1;
35 build(ls(x),l,mid);
36 build(rs(x),mid+1,r);
37 mi(x)=min(mi(ls(x)),mi(rs(x)));
38 ma(x)=max(ma(ls(x)),ma(rs(x)));
39 }
40 void add(int x,int l,int r,int y)
41 {
42 down(x);
43 if(l(x)>=l&&r(x)<=r)
44 {
45 mi(x)+=y;ma(x)+=y;la(x)+=y;
46 return;
47 }
48 int mid=(l(x)+r(x))>>1;
49 if(l<=mid)add(ls(x),l,r,y);
50 if(r>mid) add(rs(x),l,r,y);
51 mi(x)=min(mi(ls(x)),mi(rs(x)));
52 ma(x)=max(ma(ls(x)),ma(rs(x)));
53 }
54 int ask_num(int x,int l,int r,int val)
55 {
56 down(x);
57 if(ma(x)<val)return 0;
58 if(l(x)>=l&&r(x)<=r&&mi(x)>=val)
59 return r(x)-l(x)+1;
60 if(l(x)==r(x))return 0;
61 int mid=(l(x)+r(x))>>1,ans=0;
62 if(l<=mid)ans+=ask_num(ls(x),l,r,val);
63 if(r>mid) ans+=ask_num(rs(x),l,r,val);
64 return ans;
65 }
66 void downn(int x)
67 {
68 if(l(x)==r(x))return;
69 down(x);
70 downn(ls(x));
71 downn(rs(x));
72 }
73 inline int read();
74 signed main()
75 {
76 // freopen("in.txt","r",stdin);
77 // freopen("1.out","w",stdout);
78
79 n=read(),m=read(),x=read();
80 for(int i=1;i<=n;i++)w[i]=read();
81 for(int i=1;i<=n;i++)a[i]=read();
82 //暴力
83 if(m*n*n<=500000000)
84 {
85 LL ans=0;
86 for(int i=1;i<=m;i++)
87 {
88 bool pd=0;
89 for(int j=1;j<=n;j++)
90 if(w[j]<=x)
91 {
92 pd=1;ans++;
93 for(int k=1;k<=n;k++)w[k]+=a[k];
94 }
95 if(!pd)break;
96 }
97 printf("%lld\n",ans);return 0;
98 }
99 bool isdo=0;
100 {
101 LL ans=0;
102 for(int i=1;i<=n;i++)
103 if(w[i]<=x)b[i]=(x-w[i])/a[i];
104 else b[i]=-1;
105 build(1,1,n);
106 for(int i=1;i<=m;i++)
107 {
108 int tem=ask_num(1,1,n,n);
109 if(tem==n){ans+=n;add(1,1,n,-n);continue;}
110 if(!isdo)
111 {
112 downn(1),isdo=1;
113 for(int i=1;i<=n;i++)b[i]=mi(pos[i]);
114 }
115 bool pd=0;
116 for(int j=1;j<=n;j++)
117 if(b[j]>=0)
118 {
119 pd=1;ans++;
120 for(int k=1;k<=n;k++)b[k]--;
121 }
122 if(!pd)break;
123 }
124 printf("%lld\n",ans);return 0;
125 }
126 }
127 inline int read()
128 {
129 int s=0,f=1;char a=getchar();
130 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
131 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
132 return s*f;
133 }

1 #include<cstdio>
2 #include<algorithm>
3 #define LL long long
4 #define min(a,b) ((a)<(b)?(a):(b))
5 #define max(a,b) ((a)>(b)?(a):(b))
6 #define int long long
7 #define HZOI std
8 using namespace HZOI;
9 const int N=5e7+3;
10 struct node{
11 LL w,a,c,id;
12 friend bool operator < (node a,node b)
13 {
14 return a.c<b.c;
15 }
16 }t[N];
17 int n,m,k;
18 LL num,cnt;
19 LL ans,lst;
20 LL sz[N];
21 inline LL read();
22 inline LL Ask(LL );
23 inline void Add(LL ,LL );
24 main()
25 {
26 // freopen("test.in","r",stdin);
27 // freopen("2.out","w",stdout);
28 n=read(),m=read(),k=read();
29 for (int i=1; i<=n; ++i) t[i].w=read(),t[i].id=i;
30 for (int i=1; i<=n; ++i) t[i].a=read();
31 for (int i=1; i<=n; ++i) t[i].c=(k-t[i].w)/t[i].a+1,Add(i,1);
32 sort(t+1,t+n+1);
33 for (int i=1; i<=n; ++i)
34 {
35 LL l=0,r=m,tot=0;
36 while(l<=r)
37 {
38 int mid=(l+r)>>1;
39 if((n-i+1)*mid<t[i].c-lst) {tot=max(tot,mid);l=mid+1;}
40 else r=mid-1;
41 }l=tot;
42 if (cnt+l>=m) { ans+=(n-i+1)*1ll*m; break; }
43 num=l+cnt;
44 if (Ask(t[i].id)+lst+(n-i+1)*1ll*l<=t[i].c) ++lst,++num;
45 lst+=l*1ll*(n-i+1); cnt+=l;
46 ans+=num;
47 Add(t[i].id,-1);
48 }
49 printf("%lld\n",ans);
50 }
51 inline LL Ask(LL x)
52 {
53 LL res=0;
54 while (x)
55 {
56 res+=sz[x];
57 x-=x&-x;
58 }
59 return res;
60 }
61 inline void Add(LL x,LL data)
62 {
63 while (x<=n)
64 {
65 sz[x]+=data;
66 x+=x&-x;
67 }
68 }
69 inline LL read()
70 {
71 LL nn=0; char cc=getchar();
72 while (cc<'0' || cc>'9') cc=getchar();
73 while (cc>='0' && cc<='9') nn=(nn<<3)+(nn<<1)+(cc^48),cc=getchar();
74 return nn;
75 }
C. 所驼门王的宝藏
为什么没有想出来map这种东西啊……

1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<vector>
6 #include<queue>
7 #include<cmath>
8 #define MAXN 100010
9 #define LL long long
10 #define max(a,b) ((a)>(b)?(a):(b))
11 using namespace std;
12 struct edge
13 {
14 int u,v,nxt;
15 #define u(x) ed[x].u
16 #define v(x) ed[x].v
17 #define n(x) ed[x].nxt
18 #define v2(x) ed2[x].v
19 #define n2(x) ed2[x].nxt
20 }ed[1000000],ed2[1000000];
21 int first[MAXN],num_e;
22 #define f(x) first[x]
23 int first2[MAXN],num_e2;
24 #define f2(x) first2[x]
25 int n,r,c;
26 struct point
27 {
28 int x,y,t;
29 #define x(i) po[i].x
30 #define y(i) po[i].y
31 #define t(i) po[i].t
32 friend bool operator < (point a,point b)
33 {
34 return a.x==b.x?a.y<b.y:a.x<b.x;
35 }
36 }po[MAXN];
37 int du[MAXN],val[MAXN];
38 int dfn[MAXN],low[MAXN],cnt,tot;
39 int bel[MAXN],sta[MAXN],top;
40 bool ins[MAXN];
41 vector<int> scc[MAXN];
42 void tarjan(int x)
43 {
44 dfn[x]=low[x]=++cnt;
45 sta[++top]=x;ins[x]=1;
46 for(int i=f(x);i;i=n(i))
47 if(!dfn[v(i)])tarjan(v(i)),low[x]=min(low[x],low[v(i)]);
48 else if(ins[v(i)])low[x]=min(low[x],dfn[v(i)]);
49 if(dfn[x]==low[x])
50 {
51 ++tot;bel[x]=tot;scc[tot].push_back(x);
52 while(sta[top]!=x)
53 {
54 bel[sta[top]]=tot;
55 scc[tot].push_back(sta[top]);
56 ins[sta[top--]]=0;
57 }
58 ins[sta[top--]]=0;
59 }
60 }
61 vector<int> h[1000010],l[1000010];
62 inline int read();
63 inline void add(int u,int v);
64 inline void add2(int u,int v);
65 signed main()
66 {
67 n=read(),r=read(),c=read();
68 for(int i=1;i<=n;i++)x(i)=read(),y(i)=read(),t(i)=read(),h[x(i)].push_back(i),l[y(i)].push_back(i);
69 // if(n<=2500)
70 {
71 for(int i=1;i<=n;i++)
72 {
73 if(t(i)==1)
74 {
75 for(int j=0;j<h[x(i)].size();j++)if(h[x(i)][j]!=i)add(i,h[x(i)][j]);
76 }
77 if(t(i)==2)
78 {
79 for(int j=0;j<l[y(i)].size();j++)if(l[y(i)][j]!=i)add(i,l[y(i)][j]);
80 }
81 if(t(i)==3)
82 {
83 for(int j=1;j<=n;j++)
84 if(j!=i&&abs(x(i)-x(j))<=1&&abs(y(i)-y(j))<=1)add(i,j);
85 }
86 }
87 for(int i=1;i<=n;i++)
88 if(!dfn[i])tarjan(i);
89 for(int i=1;i<=num_e;i++)
90 if(bel[u(i)]!=bel[v(i)])
91 add2(bel[u(i)],bel[v(i)]),du[bel[v(i)]]++;
92 queue<int> q;
93 for(int i=1;i<=tot;i++)
94 {
95 if(!du[i])q.push(i),val[i]=scc[i].size();
96 }
97 LL ans=0;
98 while(!q.empty())
99 {
100 int x=q.front();q.pop();
101 ans=max(ans,val[x]);
102 for(int i=f2(x);i;i=n2(i))
103 {
104 val[v2(i)]=max(val[v2(i)],val[x]+scc[v2(i)].size());
105 du[v2(i)]--;
106 if(!du[v2(i)])q.push(v2(i));
107 }
108 }
109 printf("%lld\n",ans);return 0;
110 }
111 }
112 inline int read()
113 {
114 int s=0,f=1;char a=getchar();
115 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
116 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
117 return s*f;
118 }
119 inline void add2(int u,int v)
120 {
121 // cout<<u<<"->"<<v<<endl;
122 ++num_e2;
123 v2(num_e2)=v;
124 n2(num_e2)=f2(u);
125 f2(u)=num_e2;
126 }
127 inline void add(int u,int v)
128 {
129 ++num_e;
130 u(num_e)=u;
131 v(num_e)=v;
132 n(num_e)=f(u);
133 f(u)=num_e;
134 }
135 /*
136 10 7 7
137 2 2 1
138 2 4 2
139 1 7 2
140 2 7 3
141 4 2 2
142 4 4 1
143 6 7 3
144 7 7 1
145 7 5 2
146 5 2 1
147
148 */

1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<vector>
6 #include<queue>
7 #include<cmath>
8 #include<map>
9 #define MAXN 100010
10 #define LL long long
11 #define max(a,b) ((a)>(b)?(a):(b))
12 using namespace std;
13 map<int,int>mp[100010];
14 struct edge
15 {
16 int u,v,nxt;
17 #define u(x) ed[x].u
18 #define v(x) ed[x].v
19 #define n(x) ed[x].nxt
20 #define v2(x) ed2[x].v
21 #define n2(x) ed2[x].nxt
22 }ed[5000000],ed2[2000000];
23 int first[MAXN],num_e;
24 #define f(x) first[x]
25 int first2[MAXN],num_e2;
26 #define f2(x) first2[x]
27 int n,r,c;
28 struct point
29 {
30 int x,y,t;
31 #define x(i) po[i].x
32 #define y(i) po[i].y
33 #define t(i) po[i].t
34 friend bool operator < (point a,point b)
35 {
36 return a.x==b.x?a.y<b.y:a.x<b.x;
37 }
38 }po[MAXN];
39 int du[MAXN],val[MAXN];
40 int dfn[MAXN],low[MAXN],cnt,tot;
41 int bel[MAXN],sta[MAXN],top;
42 bool ins[MAXN];
43 vector<int> scc[MAXN];
44 void tarjan(int x)
45 {
46 dfn[x]=low[x]=++cnt;
47 sta[++top]=x;ins[x]=1;
48 for(int i=f(x);i;i=n(i))
49 if(!dfn[v(i)])tarjan(v(i)),low[x]=min(low[x],low[v(i)]);
50 else if(ins[v(i)])low[x]=min(low[x],dfn[v(i)]);
51 if(dfn[x]==low[x])
52 {
53 ++tot;bel[x]=tot;scc[tot].push_back(x);
54 while(sta[top]!=x)
55 {
56 bel[sta[top]]=tot;
57 scc[tot].push_back(sta[top]);
58 ins[sta[top--]]=0;
59 }
60 ins[sta[top--]]=0;
61 }
62 }
63 vector<int> h[1000010],l[1000010];
64 inline int read();
65 inline void add(int u,int v);
66 inline void add2(int u,int v);
67 signed main()
68 {
69 n=read(),r=read(),c=read();
70 for(int i=1;i<=n;i++)x(i)=read(),y(i)=read(),t(i)=read(),h[x(i)].push_back(i),l[y(i)].push_back(i),mp[x(i)][y(i)]=i;
71 {
72 for(int i=1;i<=n;i++)
73 {
74 if(t(i)==1)
75 {
76 for(int j=0;j<h[x(i)].size();j++)if(h[x(i)][j]!=i)add(i,h[x(i)][j]);
77 }
78 if(t(i)==2)
79 {
80 for(int j=0;j<l[y(i)].size();j++)if(l[y(i)][j]!=i)add(i,l[y(i)][j]);
81 }
82 if(t(i)==3)
83 {
84 if(mp[x(i)].find(y(i)-1)!=mp[x(i)].end())add(i,mp[x(i)][y(i)-1]);
85 if(mp[x(i)].find(y(i)+1)!=mp[x(i)].end())add(i,mp[x(i)][y(i)+1]);
86
87 if(x(i)>1)
88 {
89 if(mp[x(i)-1].find(y(i)-1)!=mp[x(i)-1].end())add(i,mp[x(i)-1][y(i)-1]);
90 if(mp[x(i)-1].find(y(i))!=mp[x(i)-1].end()) add(i,mp[x(i)-1][y(i)]);
91 if(mp[x(i)-1].find(y(i)+1)!=mp[x(i)-1].end())add(i,mp[x(i)-1][y(i)+1]);
92 }
93 // if(x(i)<m)
94 {
95 if(mp[x(i)+1].find(y(i)-1)!=mp[x(i)+1].end())add(i,mp[x(i)+1][y(i)-1]);
96 if(mp[x(i)+1].find(y(i))!=mp[x(i)+1].end()) add(i,mp[x(i)+1][y(i)]);
97 if(mp[x(i)+1].find(y(i)+1)!=mp[x(i)+1].end())add(i,mp[x(i)+1][y(i)+1]);
98 }
99 }
100 }
101 for(int i=1;i<=n;i++)
102 if(!dfn[i])tarjan(i);
103 for(int i=1;i<=num_e;i++)
104 if(bel[u(i)]!=bel[v(i)])
105 add2(bel[u(i)],bel[v(i)]),du[bel[v(i)]]++;
106 queue<int> q;
107 for(int i=1;i<=tot;i++)
108 {
109 if(!du[i])q.push(i),val[i]=scc[i].size();
110 }
111 LL ans=0;
112 while(!q.empty())
113 {
114 int x=q.front();q.pop();
115 ans=max(ans,val[x]);
116 for(int i=f2(x);i;i=n2(i))
117 {
118 val[v2(i)]=max(val[v2(i)],val[x]+scc[v2(i)].size());
119 du[v2(i)]--;
120 if(!du[v2(i)])q.push(v2(i));
121 }
122 }
123 printf("%lld\n",ans);return 0;
124 }
125 }
126 inline int read()
127 {
128 int s=0,f=1;char a=getchar();
129 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
130 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
131 return s*f;
132 }
133 inline void add2(int u,int v)
134 {
135 ++num_e2;
136 v2(num_e2)=v;
137 n2(num_e2)=f2(u);
138 f2(u)=num_e2;
139 }
140 inline void add(int u,int v)
141 {
142 ++num_e;
143 u(num_e)=u;
144 v(num_e)=v;
145 n(num_e)=f(u);
146 f(u)=num_e;
147 }
148 /*
149 10 7 7
150 2 2 1
151 2 4 2
152 1 7 2
153 2 7 3
154 4 2 2
155 4 4 1
156 6 7 3
157 7 7 1
158 7 5 2
159 5 2 1
160 */

1 //#####################################################31:
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<queue>
6 #include<cmath>
7 #define MAXN 100010
8 #define LL Long long
9 using namespace std;
10 struct edge
11 {
12 int v,nxt;
13 #define v(x) ed[x].v
14 #define n(x) ed[x].nxt
15 }ed[1000000];
16 int first[MAXN],num_e;
17 #define f(x) first[x]
18 int n,r,c;
19 int x[MAXN],y[MAXN],t[MAXN],du[MAXN];
20 /*
21 int dis[MAXN];
22 bool v[MAXN];
23 void spfa(int st)
24 {
25 memset(dis,0,sizeof(dis));
26 memset(v,0,sizeof(v));
27 queue<int>q;q.push(st);
28 dis[st]=1;v[st]=1;
29 while(!q.empty())
30 {
31 int x=q.front();q.pop();//v[x]=0;
32 for(int i=f(x);i;i=n(i))
33 if(dis[v(i)]<dis[x]+1)
34 {
35 dis[v(i)]=dis[x]+1;
36 if(!v[v(i)])q.push(v(i)),v[v(i)]=1;
37 }
38 }
39 }*/
40 /*void dist(int st)
41 {
42 memset(dis,0,sizeof(dis));
43 memset(v,0,sizeof(v));
44 queue<pair<int,int> >q;
45 dis[st]=1;q.push(make_pair(1,st));
46 while(!q.empty())
47 {
48 int x=q.front().second;q.pop();
49 if(v[x])continue;v[x]=1;
50 for(int i=f(x);i;i=n(i))
51 if(dis[v(i)]<dis[x]+1)
52 dis[v(i)]=dis[x]+1,
53 q.push(make_pair(dis[v(i)],v(i)));
54 }
55 }
56 */
57 inline int read();
58 inline void add(int u,int v);
59 signed main()
60 {
61 n=read(),r=read(),c=read();
62 for(int i=1;i<=n;i++)x[i]=read(),y[i]=read(),t[i]=read();
63 if(n<=2500)
64 {
65 for(int i=1;i<=n;i++)
66 for(int j=1;j<=n;j++)
67 if(i!=j)
68 {
69 if(t[i]==1&&x[j]==x[i])add(i,j),du[j]++;
70 if(t[i]==2&&y[j]==y[i])add(i,j),du[j]++;
71 if(t[i]==3&&abs(x[i]-x[j])<=1&&abs(y[i]-y[j])<=1)add(i,j),du[j]++;
72 }
73 int ans=0;
74 for(int st=1;st<=n;st++)
75 {
76 spfa(st);printf("#st:%d \n",st);
77 for(int i=1;i<=n;i++)
78 {
79 cout<<i<<" "<<dis[i]<<endl;
80 ans=max(ans,dis[i]);
81 }
82 }
83 printf("%d\n",ans);
84 return 0;
85 }
86 }
87 inline int read()
88 {
89 int s=0,f=1;char a=getchar();
90 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
91 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
92 return s*f;
93 }
94 inline void add(int u,int v)
95 {
96 cout<<u<<"->"<<v<<endl;
97 ++num_e;
98 v(num_e)=v;
99 n(num_e)=f(u);
100 f(u)=num_e;
101 }
102 /*
103 10 7 7
104 2 2 1
105 2 4 2
106 1 7 2
107 2 7 3
108 4 2 2
109 4 4 1
110 6 7 3
111 7 7 1
112 7 5 2
113 5 2 1
114
115 */
116 //##################################################################################2:
117 #include<iostream>
118 #include<cstring>
119 #include<cstdio>
120 #include<vector>
121 #include<queue>
122 #include<cmath>
123 #define MAXN 100010
124 #define LL long long
125 #define max(a,b) ((a)>(b)?(a):(b))
126 using namespace std;
127 struct edge
128 {
129 int u,v,nxt;
130 #define u(x) ed[x].u
131 #define v(x) ed[x].v
132 #define n(x) ed[x].nxt
133 #define v2(x) ed2[x].v
134 #define n2(x) ed2[x].nxt
135 }ed[1000000],ed2[1000000];
136 int first[MAXN],num_e;
137 #define f(x) first[x]
138 int first2[MAXN],num_e2;
139 #define f2(x) first2[x]
140 int n,r,c;
141 int x[MAXN],y[MAXN],t[MAXN],du[MAXN],val[MAXN];
142 int dfn[MAXN],low[MAXN],cnt,tot;
143 int bel[MAXN],sta[MAXN],top;
144 bool ins[MAXN];
145 vector<int> scc[MAXN];
146 void tarjan(int x)
147 {
148 dfn[x]=low[x]=++cnt;
149 sta[++top]=x;ins[x]=1;
150 for(int i=f(x);i;i=n(i))
151 if(!dfn[v(i)])tarjan(v(i)),low[x]=min(low[x],low[v(i)]);
152 else if(ins[v(i)])low[x]=min(low[x],dfn[v(i)]);
153 if(dfn[x]==low[x])
154 {
155 ++tot;bel[x]=tot;scc[tot].push_back(x);
156 while(sta[top]!=x)
157 {
158 bel[sta[top]]=tot;
159 scc[tot].push_back(sta[top]);
160 ins[sta[top--]]=0;
161 }
162 ins[sta[top--]]=0;
163 }
164 }
165 inline int read();
166 inline void add(int u,int v);
167 inline void add2(int u,int v);
168 signed main()
169 {
170 n=read(),r=read(),c=read();
171 for(int i=1;i<=n;i++)x[i]=read(),y[i]=read(),t[i]=read();
172 if(n<=2500)
173 {
174 for(int i=1;i<=n;i++)
175 for(int j=1;j<=n;j++)
176 if(i!=j)
177 {
178 if(t[i]==1&&x[j]==x[i])add(i,j);
179 if(t[i]==2&&y[j]==y[i])add(i,j);
180 if(t[i]==3&&abs(x[i]-x[j])<=1&&abs(y[i]-y[j])<=1)add(i,j);
181 }
182 for(int i=1;i<=n;i++)
183 if(!dfn[i])tarjan(i);
184 for(int i=1;i<=num_e;i++)
185 if(bel[u(i)]!=bel[v(i)])
186 add2(bel[u(i)],bel[v(i)]),du[bel[v(i)]]++;
187 queue<int> q;
188 for(int i=1;i<=tot;i++)
189 {
190 if(!du[i])q.push(i),val[i]=scc[i].size();
191 // printf("#scc%d %d:\n",i,du[i]);
192 // for(int j=0;j<scc[i].size();j++)
193 // cout<<scc[i][j]<<" ";
194 // puts("");
195 }
196 LL ans=0;
197 while(!q.empty())
198 {
199 int x=q.front();q.pop();
200 // cout<<x<<" "<<val[x]<<endl;
201 ans=max(ans,val[x]);
202 for(int i=f2(x);i;i=n2(i))
203 {
204 val[v2(i)]=max(val[v2(i)],val[x]+scc[v2(i)].size());
205 du[v2(i)]--;
206 if(!du[v2(i)])q.push(v2(i));
207 }
208 }
209 printf("%lld\n",ans);return 0;
210 }
211 }
212 inline int read()
213 {
214 int s=0,f=1;char a=getchar();
215 while(a<'0'||a>'9'){if(a=='-')f=-1;a=getchar();}
216 while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
217 return s*f;
218 }
219 inline void add2(int u,int v)
220 {
221 // cout<<u<<"->"<<v<<endl;
222 ++num_e2;
223 v2(num_e2)=v;
224 n2(num_e2)=f2(u);
225 f2(u)=num_e2;
226 }
227 inline void add(int u,int v)
228 {
229 // cout<<u<<"->"<<v<<endl;
230 ++num_e;
231 u(num_e)=u;
232 v(num_e)=v;
233 n(num_e)=f(u);
234 f(u)=num_e;
235 }
236 /*
237 10 7 7
238 2 2 1
239 2 4 2
240 1 7 2
241 2 7 3
242 4 2 2
243 4 4 1
244 6 7 3
245 7 7 1
246 7 5 2
247 5 2 1
248
249 */
