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 */